패키지
✒️ 2025-05-19 10:24 내용 수정
Do it! 점프 투 파이썬(2017년 발행) 내용을 정리
관련 있는 모듈의 집합
- 패키지로 Python 모듈을 계층적(디렉터리 구조)으로 관리할 수 있게 해준다.
- 모듈 참고.
- Python 패키지는 디렉터리와 모듈로 이루어진다.
dir/
moduel.py
dir2/
module2.py
패키지 만들기
- 패키지 디렉터리를 만들고, 하위에 서브 디렉터리와 모듈 파일들을 만든다.
- 각 디렉터리의 하위에
__init__.py파일을 만든다. __init__.py파일의 내용은 비워둔다.
- 각 디렉터리의 하위에
test/
__init__.py
testsub/
__init.py
greeting.py
hello.py
hello.py와greeting.py에 테스트할 내용을 작성한다.
# hello.py
def print_hello():
print("hello")
# greeting.py
def print_greeting():
print("welcome!")
test패키지를 참조할 수 있도록 작업할 명령 프롬프트에서set PYTHONPATH=패키지경로를 추가하고, Python 인터프리터를 실행한다.
- 이제 명령 프롬프트에서 패키지 안의 모듈을
import로 불러와 모듈 내의 함수를 실행한다.
- 먼저
test/testsub/greeting.py를 가져와서 테스트한다.
>>> import test.testsub.greeting
>>> test.testsub.greeting.print_greeting()
welcome!
- 이번엔
test/testsub디렉터리를from ... import로 가져와서 실행한다.- 이전에 사용한
import때문에 오류가 생길 수 있어 인터프리터를 다시 시작한 후 진행한다.
- 이전에 사용한
>>> from test.testsub import greeting
>>> greeting.print_greeting()
welcome!
__init__.py
__init__.py의 역할은 해당 디렉터리가 패키지의 일부임을 알려준다.- 패키지에 포함된 디렉터리에
__init__.py파일이 없다면 패키지로 인식되지 않는다. - Python 3.3 버전부터는
__init__.py파일이 없어도 패키지로 인식되지만, 하위 버전 호환을 위해__init__.py파일을 생성하는 것이 안전하다고 한다.
- 패키지에 포함된 디렉터리에
__init__.py파일을 사용하여 패키지와 관련된 설정이나 초기화 코드를 포함할 수 있다.
- 패키지 변수와 함수 정의
- 패키지 수준의 변수와 함수를 정의할 수 있다.
test/__init__.py에서test/testsub/greeting.py에 있는 함수를 미리import하는 구문을 작성한다.test패키지 변수인VERSION을 정의하고, 패키지 함수print_version()을 정의한다..testsub.greeting으로 작성한 것은 현재test/__init__.py파일의 위치를 기준으로testsub/greeting.py의 상대 경로를 작성한 것이다.- 상대 경로 작성 시
..는 부모 디렉터리,.는 현재 디렉터리를 의미한다.
- 상대 경로 작성 시
# test/__init__.py
from .testsub.greeting import print_greeting
VERSION = "3.13.2"
def print_version():
print(f"Python version : {VERSION}")
- 이제 명령 프롬프트에서
set PYTHONPATH=패키지경로설정이 된 상태로 Python 인터프리터를 열어test패키지를import하여 패키지에서 미리import한 함수와 패키지 변수, 패키지 함수를 테스트한다.
>>> import test
>>> test.print_greeting()
welcome!
>>> test.VERSION
'3.13.2'
>>> test.print_version()
Python version : 3.13.2
- 패키지 초기화
- 패키지를 처음 불러올 때 실행되어야 하는 코드를 작성할 수 있다.
- 최상위 패키지에서 작성한 초기화 코드는 해당 패키지의 하위 모듈의 함수를
import할 때도 실행되지만, 초기화 코드는 한 번 실행된 후 다시import할 때는 실행되지 않는다.
# test/__init__.py
from .testsub.greeting import print_greeting
VERSION = "3.13.2"
def print_version():
print(f"Python version : {VERSION}")
# 패키지 초기화
print("Initializing test package")
>>> import test
Initializing test package
__all__ 변수
- 특정 디렉터리의 모듈을
*를 사용하는 경우,import할 때는 해당 디렉터리의__init__.py파일에__all__변수를 설정하고,import할 수 있는 모듈을 정의한다.__all__에 정의된 모듈만import함을 의미한다.
- 다만
from a.b.c import *에서c가 모듈인 경우는__all__과 상관없이import된다.
>>> from test.testsub.greeting import *
Initializing test package
>>> print_greeting()
welcome!
- 테스트를 위해
test/__init__.py에서import를 제거한다.
# test/__init__.py
VERSION = "3.13.2"
def print_version():
print(f"Python version : {VERSION}")
# 패키지 초기화
print("Initializing test package")
- 명령 프롬프트에서 Python 인터프리터를 실행하고,
from ... import *를 사용하여test/testsub하위의 모듈을 모두 불러오도록 시도한다.greeting이라는 모듈을 찾지 못해 에러가 생긴다.
>>> from test.testsub import *
Initializing test package
>>> greeting.print_greeting()
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
greeting.print_greeting()
^^^^^^^^
NameError: name 'greeting' is not defined
test/testsub/__init__.py파일에서__all__변수에test/testsub/하위 모듈의 이름을 리스트로 정의한다.
# test/testsub/__init__.py
__all__ = ['greeting']
- 다시 Python 인터프리터에서
from ... import *를 수행하여 확인한다.
>>> from test.testsub import *
Initializing test package
>>> greeting.print_greeting()
welcome!