Programming 기초/Python

[Python 기초 #9] 패키지

코딩상륙작전 2023. 4. 27. 15:45

* 패키지(Packages)

도트(.)를 사용하여 파이썬 모듈을 계층적(디렉터리 구조)으로 관리할 수 있게 해준다.

 

* 패키지 만들기

 

예) 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

 

여기서 gmae, sound, graphic, play는 디렉터리 이름이고 확장자가 .py인 파일은 파이썬 모듈, game 디렉터리가  이 패키지의 루트 디렉터리이고 sound, graphic, play는 서브 디렉터리이다.

 

1. 서브 디렉터리(폴더)를 만들고 빈 파일의 모듈을 만들어 놓는다. 

2. echo모듈과 render 모듈은 아래와 같이 내용을 작성해준다.

# echo.py
def echo_test():
    print("echo")
# render.py
def render_test():
    print("render")

 

3. set 명령어로 PYTHONPATH 환경 변수에 C:\~game 디렉터리를 추가한다. [python 기초 #8] 모듈 참고.

4. import로 패키지 내의 모듈을 불러온다.(다음 예제들을 import하기 전마다 인터프리터를 종료하고 다시 실행할 것.)

>>> import game.sound.echo
>>> game.sound.echo.echo_test()
echo
>>> ^Z	# 윈도우의 경우 인터프리터 종료 단축키
>>> from game.sound import echo
>>> echo.echo_test()
echo
>>> ^Z
>>> from game.sound.echo import echo_test
>>> echo_test()
echo
>>> ^Z

 

* _ _init_ _.py의 용도

_ _init_ _.py 파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다. 

>>> from game.sound import*
>>> echo.echo_test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'echo' is not defined

 

이렇게 특정 디렉터리의 모듈을 *을 사용하여 import할 때에는 다음과 같이 해당 디렉터리의 _ _init_ _.py파일에 _ _all_ _ 변수를 설정하고 import 할 수 있는 모듈을 정의해 주어야 오류가 발생하지 않는다.

# sound 파일에 있는 __init__.py안에 아래 문장을 넣어준다.
__all__ = ['echo']

여기에서 _ _all_ _이 의미하는 것은 sound 디렉터리에서 * 기호를 사용하여 import할 경우 이곳에 정의된 echo 모듈만 import된다는 의미이다.

# __all__ 변수 설정 후 정상적으로 작동
>>> from game.sound import*
>>> echo.echo_test()
echo

 

* relative 패키지

render.py 모듈이 sound 디렉터리의 echo.py 모듈을 사용하고 싶을 때 두 가지 방법이 있다.

1. 기본적인 추가 방법. 아래와 같이 render.py에 echo_test를 import해준다.

# render.py
from game.sound.echo import echo_test 


def render_test():
    print("render")
    echo_test()
>>> from game.graphic.render import render_test
>>> render_test()
render
echo

2. relative 패키지

# render.py
from ..sound.echo import echo_test


def render_test():
    print("render")
    echo_test()
  • 여기에서 ..은 부모 디렉터리를 의미한다. graphic과 sound 디렉터리는 동일한 깊이(depth)이므로 부모 디렉터리(..)을 사용하여 위와 같은 import가 가능한 것이다.
  • ..과 같은 relative한 접근자는 모듈 안에서만 사용해야 한다. 파이썬 인터프리터에서 사용하면 오류가 발생한다.
>>> from game.graphic.render import render_test
>>> render_test()
render
echo