패키지(Package)
여러 모듈(module)들을 폴더(디렉터리) 단위로 묶어서 구성(관련 있는 모듈의 집합)
패키지를 사용하면, 코드를 체계적으로 관리하고 네임스페이스(namespace) 를 구분하기 수월해짐
파이썬 모듈을 계층적(디렉터리 구조)으로 관리할 수 있게 해줌
game/
__init__.py
sound/
__init__.py
echo.py
wav.py
graphic/
__init__.py
screen.py
render.py
play/
__init__.py
run.py
test.py
위와 같은 구조가 있으면, mypackage가 패키지이고, module_a.py, module_b.py가 이 패키지 안에 들어 있는 모듈
---🐢
모듈과 패키지
모듈(Module)
파이썬 파일(.py 파일) 하나가 모듈
모듈 안에는 함수, 클래스, 변수, 상수, 실행 가능한 코드 등이 정의되어 있을 수 있음
패키지(Package)
디렉터리로, 모듈의 집합
# 파이썬 3.3 이상에서는 __init__.py파일이 없어도 폴더를 패키지로 인식하지만, 하위 호환성 등을 위해 여전히 패키지 폴더 안에 보통 __init__.py파일을 포함
--🐢-
__init__.py
이전까지 파이썬 2.x~3.2까지는 패키지 폴더로 인식되려면 __init__.py 파일이 반드시 존재해야 했음
파이썬 3.3부터는 Implicit Namespace Packages 라는 기능이 추가되어, __init__.py가 없어도 패키지로 동작 가능
하지만 __init__.py는 패키지를 초기화하는 스크립트로서, 패키지를 임포트할 때 자동으로 실행
__init__.py의 다양한 활용
패키지 전체에서 공통으로 필요한 변수와 함수 정의
# C:/doit/game/__init__.py
VERSION = 4.0
def print_version_info():
print(f"The version of this game is {VERSION}.")
# 사용법
>>> import game
>>> print(game.VERSION)
4.0
>>> game.print_version_info()
The version of this game is 4.0.
패키지 내 모듈을 미리 import
# C:/doit/game/__init__.py
from .graphic.render import render_test
# .graphic.render의 맨 앞 .은 현재 디렉터리를 의미
VERSION = 3.5
def print_version_info():
print(f"The version of this game is {VERSION}.")
# 사용법
>>> import game
>>> game.render_test()
render
패키지 초기화
# C:/doit/game/__init__.py
from .graphic.render import render_test
VERSION = 3.5
def print_version_info():
print(f"The version of this game is {VERSION}.")
# 여기에 패키지 초기화 코드를 작성한다.
print("Initializing game ...")
# 사용법
>>> import game
Initializing game ...
>>>
## 처음 import할 때 초기화 코드 실행
## 패키지의 하위 모듈의 함수를 import할 경우에도 실행
## 초기화 코드는 한 번 실행된 후에 다시 import 수행하더라도 실행 X
-🐢--
패키지 임포트와 사용 예시
mypackage/ # 패키지 디렉터리
├─ __init__.py # 패키지 초기화
├─ module_a.py # 모듈 A
├─ module_b.py # 모듈 B
└─ subpackage/ # 서브패키지
├─ __init__.py
└─ module_c.py
패키지 임포트
import mypackage
# mypackage/__init__.py 실행
# 패키지 내부 모듈 module_a, module_b는 아직 임포트되지 않을 수도 있음
특정 모듈 임포트
import mypackage.module_a
# module_a를 명시적으로 임포트하면, 해당 모듈의 모든 내용(함수, 클래스 등)을 사용할 수 있음
# 사용 예: mypackage.module_a.some_function()
from mypackage import module_a
# module_a.some_function() 으로 접근 가능
모듈 안의 특정 함수나 클래스만 임포트
from mypackage.module_a import some_function
some_function()
패키지 내부에서 하위 모듈 참조
같은 패키지 안에서 다른 모듈을 참조하려면 relative import 사용
# module_b.py 내부
from .module_a import some_function # . 은 현재 디렉터리(mypackage)를 의미
# relative한 접근자: .. 부모 디렉터리 의미 / . 현재 디렉터리 의미
🐢---
(참고) __all__
모듈 또는 패키지 내에서 from ... import * 구문을 사용했을 때, 어떤 네임들을 임포트할지 지정
기본적으로 from mymodule import *를 하면, 해당 모듈 내 밑줄(_)로 시작하지 않는 모든 네임을 임포트 -> 모듈 내부에 __all__리스트를 정의해 두면, from ... import *가 실행될 때 __all__에 포함된 네임만 임포트
# mymodule.py
__all__ = ["func_a", "MyClass"]
def func_a():
pass
def func_b():
pass
class MyClass:
pass
class MyClass2:
pass
from mymodule import * 를 하면, func_a와 MyClass만 임포트 / func_b, MyClass2는 임포트 X
# mypackage/__init__.py
__all__ = ["module_a", "module_b"]
print("mypackage is imported!")
from mypackage import * 시 module_a, module_b만 임포트
# 주의 사항: __all__은 import * 구문에만 영향; import mymodule 혹은 from mymodule import some_name 같이 명시적으로 임포트할 때에는 __all__ 리스트가 영향 X
'언어 > Python' 카테고리의 다른 글
파이썬 내장 함수 (0) | 2025.01.05 |
---|---|
예외 처리 (0) | 2025.01.02 |
클래스/객체/인스턴스 (0) | 2025.01.01 |
함수(Function) (0) | 2024.12.31 |
리스트 컴프리헨션 (1) | 2024.12.30 |