IT/파이썬

[코딩도장] day33. 파이썬: 모듈과 패키지 만들기

_하늘여우_ 2020. 10. 9. 17:06

출처 : unsplash

■ 들어가기

- 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


▶ Unit45. 모듈과 패키지 만들기

     - 45.1 모듈 만들기

     - 45.2 모듈과 시작점 알아보기

     - 45.3 패키지 만들기

     - 45.4 패키지에서 from import 응용하기

 

 

0. 들어가기

- 파이썬 스크립트 작성 시 매번 비슷한 클래스와 함수를 작성한다면 공통되는 부분을 빼내서 모듈과 패키지로 만들어 필요시마다 패키지만 가져와 사용

- 모듈(module): 변수, 함수, 클래스 등을 모아 놓은 스크립트 파일

- 패키지(package): 여러 모듈을 묶은 것

- 모듈은 간단한 기능을 담을 때 사용, 패키지는 코드가 많고 복잡할 때 사용

- 패키지는 기능들이 모듈 여러 개로 잘게 쪼개져 있고, 관련된 모듈끼리 폴더에 모여 있는 형태

 

 

>> 45.1 모듈 만들기 <<

- 아래는 간단하게 2의 거듭제곱을 구하는 모듈로써 확장자 .py를 제외하면 모듈 이름이 됨 

square.py

base = 2    # 변수

def square(n) :     # 함수

    return base ** n

 

 

1. 모듈 사용하기

- 앞서 만든 square2 모듈 사용

- 호출할 main.py와 square2.py는 동일 디렉토리에 존재하여야 함

import 모듈

모듈.변수

모듈.함수()

- import로 모듈을 가져온 뒤 모듈.변수, 모듈.함수() 형식으로 사용

소스 (main.py)

결과

import square2              # import로 square2 모듈 가져옴

print(square2.base)         # 모듈.변수 형식으로 모듈의 변수 사용

print(square2.square(10))   # 모듈.함수() 형식으로 모듈의 함수 사용

2

1024

 

2. from import 로 변수, 함수 가져오기

- 사용법 : from 모듈 import 변수, 함수

>>> from square2 import base, square

>>> print(base)

2

>>> square(10)

1024

 

3. 모듈에 클래스 작성하기

소스 (person.py)

class Person : # 클래스

    def __init__(self, name, age, address) :

        self.name = name

        self.age = age

        self.address = address

    def greeting(self) :

        print('안녕하세요. 저는 {0}입니다.'.format(self.name))

- main.py 를 수정

import 모듈

모듈.클래스()

소스 (main.py)

결과

import person       # import 로 person 모듈을 가져옴

# 모듈.클래스() 로 person 모듈의 클래스 사용

maria = person.Person('마리아', 20, '서울시 서초구 반포동')

maria.greeting()

안녕하세요. 저는 마리아입니다.

 

4. from import로 클래스 가져오기

- 사용법 : from 모듈 import 클래스

>>> from person import Person

>>> maria = Person('마리아', 20, '서울시 서초구 반포동')

>>> maria.greeting()

안녕하세요. 저는 마리아입니다.

출처 : 파이썬 코딩 도장 (dojang.io)

 

 

>> 45.2 모듈과 시작점 알아보기 <<

- if __name__ == '__main__' ??

- 모듈 생성

소스 (hello2.py)

print('hello 모듈 시작')

print('hello.py __name__: ', __name__)          # __name__ 변수 출력

print('hello 모듈 끝')

- main.py

소스 (main.py)

결과

import hello2       # hello2 모듈을 가져옴

print('main.py __name__: ', __name__)     # __name__ 변수 출력

hello 모듈 시작

hello.py __name__:  hello2

hello 모듈 끝

main.py __name__: __main__

- hello 모듈 시작 ~ hello 모듈 끝           // hello2.py 수행부분으로 __name__에 hello2 모듈 이름이 들어감

- main.py __name__: __main__        // main.py 수행부분으로 __name__ 에 main 이름이 들어감

- 어떤 스크립트 파일이든 파이썬 인터프리터가 최초로 실행한 스크립트 파일의 __name__ 에는 '__main__' 이 들어감

- 즉, 프로그램의 시작점(entry point) 이라는 의미

 

- 파이썬에서 import 로 모듈을 가져오면 해당 스크립트 파일이 한 번 실행됨

- 따라서 hello2 모듈을 가져오면 hello2.py 안의 코드가 실행됨

hello2.py 를 모듈로 가져온 경우 (출처 : 파이썬 코딩 도장 (dojang.io))
hello2.py 를 단독으로 실행한 경우 (출처 : 파이썬 코딩 도장 (dojang.io))

[잠깐] 

if __name__ == '__main__' :               

# 이 경우 현재 스크립트 파일이 프로그램의 시작점이 맞는지 판단하는 작업

# 즉, 스크립트 파일이 메인 프로그램으로 사용될 때와 모듈로 사용될 때를 구분하기 위한 용도임

 

 

 

1. 스크립트 파일로 실행하거나 모듈로 사용하는 코드 만들기

소스 (calc.py)

결과

def add(a, b) :

    return a + b

def mul(a, b) :

    return a * b

if __name__ == '__main__' :     # 프로그램의 시작점일 때만 아래 코드 실행

    print(add(10, 20))

    print(mul(10, 20))

30

200

- 스크립트 자체를 수행할 경우 __name__ 은 __main__ 이 되기 때문에 print 코드가 출력됨

- 위의 스크립트가 모듈로 사용된 경우

>>> import calc

>>> 

- import 로 calc를 모듈로 호출한 경우 calc.py 안의 스크립트가 한 번 수행되지만,

  모듈로 사용되었기 때문에 __name__은 모듈이름인 calc로 설정됨

- 따라서 이 경우 print 는 수행되지 않음

- 해당 모듈의 함수를 직접 호출하여 수행

>>> import calc

>>> calc.add(50, 60)

110

>>> calc.mul(50, 60)

3000

 

[잠깐] 시작점??

- java 나 C 언어의 경우 시작 함수(main)를 따로 정해 여러 소스 파일 들 중에서 시작점을 구분하기 위한 용도로 사용되지만

- 파이썬은 스크립트 언어가 기반이고,

  스크립트 파일은 파일 한 개로 이루어져 파일 자체가 하나의 프로그램으로써 별도로 시작점이 필요하지 않음

- 다만, 시작점 구분이 필요한 경우 __name__ == '__main__' 의 조건으로 시작점 구분 가능함

 

 

>> 45.3 패키지 만들기 <<

- 모듈은 스크립트 파일이 한 개지만 패키지는 폴더(디렉토리)로 구성됨

- 예제로 사용될 패키지 폴더 구성

출처 : 파이썬 코딩 도장 (dojang.io)

 

- 먼저 c:\project 안에 caclpkg 폴더 생성

- calcpkg 폴더 내 __init__.py 파일 생성

  └ 폴더(디렉토리) 안에 __init__.py 파일이 있으면 해당 폴더는 "패키지" 로 인식되며, 해당 파일 내용은 비워둘 수 있음

( 파이썬 3.3 이상 버전부터는 __init__.py 파일이 없어도 패키지로 인식되지만, 하위버전에서는 반드시 존재해야 함 )

소스 (calcpkg/__init__.py)

# __init__.py 파일은 내용을 비워 둘 수 있음

 

1. 패키지에 모듈 만들기

- calcpkg 내 2개 모듈 생성

- operationg 모듈 : 덧셈, 곱셈 합수 존재

- geoetry 모듈 : 삼각형, 사각형의 넓이 계산 함수 존재

소스 (calcpkg/operation.py)

def add(a, b) :

    return a + b

def mul(a, b) :

    return a * b

소스 (calcpkg/geometry.py)

def triangle_area(base, height) :

    return base * height / 2

def rectangle_area(width, height) :

    return width * height

 

2. 패키지 사용하기

- 목적 : 스크립트 파일에서 패키지의 모듈 사용하기

- main.py 파일은 calcpkg 패키지 폴더 상위에 존재해야 함

소스 (main.py)

결과

import calcpkg.operation        # calcpkg 패키지의 operation 모듈 가져옴

import calcpkg.geometry         # calcpkg 패키지의 geometry 모듈 가져옴

print(calcpkg.operation.add(10, 20))    # operation 모듈의 add 함수 사용

print(calcpkg.operation.mul(10, 20))    # operation 모듈의 mul 함수 사용

print(calcpkg.geometry.triangle_area(30, 40))   # geometry 모듈의 triangle_area 함수 사용

print(calcpkg.geometry.rectangle_area(30, 40))  # geometry 모듈의 rectangle_area 함수 사용

30

200

600.0

1200

- 패키지의 모듈/함수 가져올 때는 어떻게 사용한다??

- import 패키지.모듈

- import 패키지.모듈.함수()

 

 

3. from import로 패키지의 모듈에서 변수, 함수, 클래스 가져오기

- 사용법

from 패키지.모듈 import 변수

from 패키지.모듈 import 함수

from 패키지.모듈 import 클래스

>>> from calcpkg.operation import add, mul

>>> add(10, 20)

30

>>> mul(10, 20)

200

- calcpkg 패키지 계층

- main.py 파일이 있는 폴더에 calcpkg 패키지가 있고,

  calcpkg 패키지 폴더 안에 __init__.py, operation.py, geometry.py 파일이 존재

출처 : 파이썬 코딩 도장 (dojang.io)

[참고] 패키지의 모듈과 __name__

- 패키지 내 모듈에서는 __name__ 변수에 패키지.모듈 형식의 이름이 지정됨

 

 

>> 45.4 패키지에서 from import 응용하기 <<

- import calcpkg 처럼 import 패키지 형식으로 패키지만 가져와 모듈을 사용하고 싶은 경우에는?

- calcpkg 패키지의 __init__.py 파일에 모듈을 from import 함

from . import 모듈

- clacpkg의 시작점을 __init__.py로 설정하는 건데, 해당 시작점에서 다시 모듈을 로딩해 놓고 사용하기 위함임

소스 (calcpkg/__init__.py)
from . import operation                # 현재 패키지에서 operation 모듈을 가져옴
from . import geometry                # 현재 패키지에서 geometry 모듈을 가져옴

- main.py 에서 패키지만 가져오도록 수정 : import calcpkg

소스 (main.py) 결과
import calcpkg      # calcpkg 패키지만 가져옴

print(calcpkg.operation.add(10, 20))    # operation 모듈의 add 함수 사용
print(calcpkg.operation.mul(10, 20))    # operation 모듈의 mul 함수 사용

print(calcpkg.geometry.triangle_area(30, 40))   # geometry 모듈의 triangle_area 함수 사용
print(calcpkg.geometry.rectangle_area(30, 40))  # geometry 모듈의 rectangle_area 함수 사용
30
200
600.0
1200

 

1. from import로 패키지에 속한 모든 변수, 함수, 클래스 가져오기

- __init__.py 에 현재 패키지(calcpkg)의 모듈 내 함수, 클래스를 가져올 수 있도록 from import 사용

- [__init__.py] from .모듈 import 변수, 함수, 클래스

- 현재 패키지란 것을 명시적으로 나타내기 위해 모듈 앞에 .(점)을 표기

- [main.py] from 패키지 import *

소스 (calcpkg/__init__.py) 결과
# 현재 패키지의 operation, geometry 모듈에서 각 함수를 가져옴
from .operation import add, mul
from .geometry import triangle_area, rectangle_area
 
소스 (main.py) 결과
from calcpkg import *       # calcpkg 패키지의 모든 변수, 함수, 클래스 가져옴

print(add(10, 20))      # operation 모듈의 add 함수 사용
print(mul(10, 20))      # operation 모듈의 mul 함수 사용

print(triangle_area(30, 40))    # geometry 모듈의 triangle_area 함수 사용
print(rectangle_area(30, 40))   # geometry 모듈의 rectangle_area 함수 사
30
200
600.0
1200

- __init__.py 에서 특정 함수(변수, 클래스)를 지정하지 않고 * 를 사용해서 모든 함수(변수, 클래스)를 가져와도 무방함

- 사용법 : from .모듈 import *

- 패키지의 __init__.py 에서 모든 변수, 함수, 클래스를 가져오는 경우, 해당 패키지를 가져오는 스크립트에서는 패키지.함수() 형식으로 사용

import 패키지

패키지.변수

패키지.함수()

패키지.클래스()