차밍이
[Python] 패키지 구성을 위해 __init__ 파일과 __all__에 대해 알아보자 본문
목차
1. example package shapes
구조
__init__
과 __all__
를 알기 위해서 예시로 사용할 package shapes
의 구조와 코드를 먼저 보고가자.
tree
shapes/
__init__.py
area.py
volume.py
shapes/area.py
PI = 3.14
# 원의 면적을 구해 주는 함수
def circle(radius):
return PI * radius * radius
# 정사각형의 면적을 구해 주는 함수
def square(length):
return length * length
shapes/volume.py
PI = 3.14
# 구의 부피를 구해 주는 함수
def sphere(radius):
return (4/3) * PI * radius * radius * radius
# 정육면체의 부피를 구해 주는 함수
def cube(length):
return length * length * length
2. __init__
파일이란?
패키지 안에는 __init__.py
라는 파일이 있습니다.
__init__.py
파일 (지금부터는 그냥 init 파일이라고 하겠습니다) 은 '이 폴더는 파이썬 패키지다'라고 말해 주는 파일입니다.
파이썬 3.3 이전 버전에서는 init 파일이 필수였습니다.
파이썬 3.3 이후 버전부터는 init 파일이 필수가 아니게 됐지만 파이썬 하위 버전과의 호환성과 패키지의 명확성을 위해 항상 패키지 안에 init 파일을 만들어 주는 것을 권장 드립니다.
처음으로 패키지나 패키지 안에 있는 어떤 것을 임포트하면 가장 먼저 패키지의 init 파일에 있는 코드가 실행됩니다.
3. __init__
파일 활용하기
init 파일을 어떻게 활용하는지 정리해 봅시다.
3-1. __init__
파일에서 임포트 사용하기
패키지를 임포트하면 기본적으로 패키지 안에 있는 내용은 임포트되지 않습니다. 패키지를 임포트할 때 패키지 안에 있는 내용도 함께 임포트하고 싶다면 init 파일을 활용해야 합니다.
init 파일에 패키지와 함께 임포트하고 싶은 것들을 써 주면 됩니다.
shapes/__init__.py
from shapes import area, volume
그러면 이제 shapes
패키지를 임포트하면 area
랑 volume
모듈도 임포트되겠죠? init 파일에서 임포트하는 것은 패키지 안으로 임포트된다고 생각하시면 됩니다. area
랑 volume
모듈은 아래와 같이 접근할 수 있습니다.
run.py
import shapes
print(shapes.area.circle(2))
print(shapes.volume.sphere(2))
그리고 모듈 대신 모듈의 함수들을 직접 임포트할 수도 있습니다.
shapes/__init__.py
from shapes.area import circle, square
그러면 우리는 이 함수들을 아래와 같이 접근할 수 있습니다.
run.py
import shapes
print(shapes.circle(2))
print(shapes.square(3))
shapes
패키지 안에서 함수들을 직접 가져왔기 때문에 area
를 건너뛸 수 있는 거죠. init 파일에서 임포트되는 것은 항상 package.
으로 접근할 수 있습니다. 위 처럼 호출 방식을 바꿔주는 것은 유용하게 쓰일 때도 있습니다.
3-2. __init__
파일에서 변수 정의하기
상수값 PI
는 area
모듈에서도 쓰이고 volume
모듈에서도 쓰입니다. PI
처럼 패키지에 있는 여러 모듈이 필요로 하는 것들은 각 모듈에서 정의하지 않고 패키지 안에서 한 번만 정의해 주는 게 좋습니다. 똑같은 걸 여러 번 정의하는 건 비효율적이고 실수로 하나를 잘 못 정의하면 프로그램에 오류가 나기 때문입니다.
PI
를 패키지 안에서 한 번만 정의해 주려면 (즉 패키지 레벨에서 정의해 주려면) PI
를 shapes
패키지의 init 파일에서 정의해 주면 됩니다.
shapes/__init__.py
PI = 3.14
그리고 패키지 안에 있는 모듈에서는 PI
를 임포트하면 됩니다.
shapes/area.py
from shapes import PI
# 원의 면적을 구해 주는 함수
def circle(radius):
...
shapes/volume.py
from shapes import PI
# 구의 부피를 구해 주는 함수
def sphere(radius):
...
PI
같은 상수뿐만이 아니라 여러 모듈에서 필요한 변수, 함수 또는 객체는 패키지의 init 파일에서 정의해 주는 게 좋습니다.
그리고 패키지의 init 파일에서 정의되는 것들은 패키지 밖에서도 사용할 수 있습니다.
run.py
# PI 직접 임포트
from shapes import PI
# 패키지 임포트 후 shapes. 으로 접근
import shapes
shapes.PI
4. __all__
특수 변수란?
__all__
특수 변수는 우리가 import \*
를 했을 때 임포트 대상에서 어떤 것들을 가져와야 하는지를 정해 주는 변수입니다. 임포트 대상에서 내용 전체를 가져오라고 했을 때 '전체'가 무엇인지 정의해 주는 거죠. __all__
은 모듈에도 적용되고 패키지에도 적용됩니다.
5. __all__
변수 활용하기
5-1. import *
모듈을 임포트할 때 from <module> import *
를 하면 모듈의 모든 내용이 임포트됩니다.
하지만 모듈 대신 패키지에 from <package> import *
를 하면 패키지 안에 있는 게 아무것도 임포트되지 않습니다.
5-2. __all__
과 모듈
모듈의 __all__
은 모듈에 해당하는 파일에서 정의합니다. 예를 들어 area.py에 아래와 같은 코드를 추가해 주면:
shapes/area.py
# __all__ 정의
__all__ = ['circle', 'square']
PI = 3.14
# 원의 면적을 구해 주는 함수
def circle(radius):
return PI * radius * radius
# 정사각형의 면적을 구해 주는 함수
def square(length):
return length * length
from shapes.area import *
를 했을 때 area
모듈의 모든 내용이 임포트되지 않고 circle
과 square
함수만 임포트됩니다.
5-3. __all__
과 패키지
패키지의 __all__
은 패키지에 해당하는 init 파일에서 정의합니다. 예를 들어 shapes
패키지의 init 파일에 아래와 같은 코드를 추가해 주면:
shapes/__init__.py
# __all__ 정의
__all__ = ['area', 'volume']
이제 from shapes import *
를 하면 area
모듈과 volume
모듈이 임포트됩니다.
__all__
을 사용하면 패키지나 모듈에 import *
를 했을 때 어떤 것들이 임포트되는지를 제어할 수 있습니다. 그래도 여전히 import *
만 봐서는 정확히 어떤 것들이 임포트되는지를 알 수 없기 때문에 import *
는 프로그램에서 정의되는 이름들, 즉 네임스페이스를 완벽히 이해하고 있을 때만 사용하는 것을 추천드립니다.
6. Reference
Codeit 강의 파이썬 중급 교육 자료
'파이썬 > 기본 문법 정리' 카테고리의 다른 글
[Python] 파일 및 폴더 디렉토리 삭제하는 법 총정리 (0) | 2022.12.13 |
---|---|
[Python] datetime 모듈 날짜 시간 포맷 맞추기와 포맷 코드 종류 (0) | 2022.07.08 |
[Python] Pandas 판다스는 과연 빠른가 ? 속도확인 value_counts, unique, drop_duplicates (0) | 2022.06.29 |
[Python] 멀티 프로세싱 사용하기 - 멀티 프로세싱 적용을 위한 함수들 알아보자 (0) | 2022.06.08 |
[Python] 파이썬 패키지란? - package에 대한 설명 및 예시 (0) | 2022.06.05 |
[Python] 모듈 vs 스크립트 vs 패키지 차이점을 알아보자 (0) | 2022.06.04 |
[Python] Scatter Plot Animation - 영상 그래프 제작 (0) | 2022.04.21 |
[Python] 판다스 apply - 함수에 복수 인자 적용하기 (2) | 2022.03.02 |