패키지(Packages)는 도트(.)를 이용하여 파이썬 모듈을 계층적(디렉터리 구조)으로 관리할 수 있게 해준다.
예를 들어 모듈명이 A, B인 경우 A는 패키지명이 되고 B는 A패키지의 B모듈이 된다.
🔔 예) 가상의 game 패키지 예
game/
__init__.py
sound/
__init__.py
echo.py
wav.py
graphic/
__init__.py
screen.py
render.py
play/
__init__.py
run.py
test.py
game, sound, graphic, play는 디렉터리명이고 .py 확장자를 가지는 파일은 파이썬 모듈이다. game 디렉터리가 이 패키지의 루트 디렉터리이고, sound, graphic, play는 서브 디렉터리이다.
📌 패키지 기본 구성 요소 준비하기
1. D:/Python 이라는 디렉터리 밑에 game 및 기타 서브 디렉터리들을 생성하고 .py 파일들을 다음과 같이 만든다.
C:/Python/game/__init__.py
C:/Python/game/sound/__init__.py
C:/Python/game/sound/echo.py
C:/Python/game/graphic/__init__.py
C:/Python/game/graphic/render.py
2. 각 디렉터리에 __init__.py 파일을 만들어 놓기만 하고 내용은 비워 둔다.
3. echo.py 파일은 다음과 같이 만든다.
# echo.py
def echo_test():
print("echo")
4. render.py 파일은 다음과 같이 만든다.
# render.py
def render_test():
print("render")
5. 다음 예제들을 수행하기 저에 game 패키지를 참조할 수 있도록 도스 창에서 set명령을 이용하여 PYTHONPATH 환경 변수에 등록한다.
첫 번째는 echo 모듈을 import하여 실행하는 방법으로, 다음과 같이 실행한다.
두 번째는 echo모듈이 있는 디렉터리까지를 from ... import 하여 실행하는 방법이다.
세번째는 echo모듈의 echo_test 함수를 직접 import하여 실행하는 방법이다.
하지만 다음과 같이 echo_test함수를 사용하는 것은 불가능하다.
import game을 수행하면 game 디렉터리의 모듈 또는 game 디렉터리의 __init__.py 에 정의된 것들만 참조할 수 있다.
또 다음처럼 echo_test 함수를 사용하는 것도 불가능하다.
도트 연산자(.)를 사용해서 import a.b.c처럼 import 할 때 사장 마지막 항목인 c는 반드시 모듈 또는 패키지여야만 한다.
__init__.py 파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다. 만약 game, sound, graphic 등 패키지에 포함된 디렉터리에 __init__.py 파일이 없다면 패키지로 인식되지 않는다.
(※ Python3.3 버전부터는 __init__.py 파일 없이도 패키지로 인식이된다. 하지만 하위 버전 호환을 위해 __init__.py 파일을 생성하는 것이 안전한 방법이다.)
game.sound 패키지에서 모든 것(*)을 import 하였으나 echo모듈을 사용할 수 없다.
이렇게 특정 디렉터리의 모듈을 *을 이용하여 import 할 때에는 다음과 같이 해당 디렉터리의 __init__.py 파일에 __all__이라는 변수를 설정하고 import할 수 있는 모듈을 정의해 주어야 한다.
__all__ = ['echo']
위와 같이 __init__.py 파일을 변경한 후 위 예제를 수행하면 원하던 결과가 출력되는 것을 확인할 수 있다.
만약 graphic 디렉터리의 render.py 모듈이 sound 디렉터리의 echo.py 모듈을 사용하고 싶다면 다음과 같이 render.py를 수정하면 가능하다.
# render.py
from gams.sound.echo import echo_test
def render_test():
print("render")
echo_test
이렇게 수정한 후 다음과 같이 수행한다.
위 예제처럼 전체 경로를 이용하여 import할 수도 있지만 다음과 같이 relative 하게 import하는 것도 가능하다.
# render.py
from ..sound.echo import echo_test
def render_test():
print("render")
echo_test()
부모 디렉터리(..)를 이용하여 위와 같은 import가 가능한 것이다.
.. // 부모 디렉터리
. // 현재 디렉터리
[Python] 내장 함수 (0) | 2017.07.19 |
---|---|
[Python] 예외 처리 (0) | 2017.07.18 |
[Python] 모듈 (0) | 2017.07.17 |
Python 클래스/클래스 변수 (0) | 2017.07.17 |
Python 파일 읽고 쓰기/with (0) | 2017.07.17 |