곰퓨타의 SW 이야기

[python] 패키지 뿌시기 본문

TIL/코테개념_python

[python] 패키지 뿌시기

곰퓨타 2021. 1. 7. 16:43

패키지는 자바에서 묶어서 사용할 때 썼던 것 같은데 이 또한 명확한 개념이 없는 것 같다.

따라서 점프투 파이썬를 통해 이 책에서 소개하는 패키지를 공부해보고자 한다.

 

물론 이 글 또한 점프투 파이썬을 볼 것이다!!

[내사랑 점프투 파이썬❣️]

wikidocs.net/1418

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

 

패키지 ?!?

패키지는 '.'을 사용하여 파이썬 모듈을 계층적으로 관리할 수 있게 해준다. 모듈 이름이 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. doit 디렉토리 밑에 game 및 서브 디렉토리를 생성하고, .py 파일들을 만든다.

C:/doit/game/__init__.py
C:/doit/game/sound/__init__.py
C:/doit/game/sound/echo.py
C:/doit/game/graphic/__init__.py
C:/doit/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 패키지를 참조하기 위해 PYTHONPATH 환경 변수에 doit 디렉토리 경로를 추가한다.

 

패키지 안의 함수 실행하기

패키지를 사용하여 echo.py 파일의 echo_test 함수를 실행한다고 해보자.

1. echo 모듈을 import 하여 실행

>>> import game.sound.echo
>>> game.sound.echo.echo_test()
echo

 

2. echo 모듈이 있는 디렉토리까지를 from ... import 하여 실행

>>> from game.sound import echo
>>> echo.echo_test()
echo

 

3. echo모듈의 echo_test 함수를 직접 import하여 실행

>>> from game.sound.echo import echo_test
>>> echo_test()
echo

 

※불가능한 경우

1. import game을 수행하면 game 디렉토리의 모듈 또는 game 디렉토리의 __init__.py에 정의한 것만 사용 가능하다.

>>> import game
>>> game.sound.echo.echo_test()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'sound'

 

2. '.' 도트 연산자를 사용해서 import a.b.c처럼 Import하는 경우, 가장 마지막 항목인 c는 반드시 모듈 또는 패키지여야 한다.

>>> import game.sound.echo.echo_test
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
ImportError: No module named echo_test

 

__init__.py의 용도

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

(python 3.3 버전부터는 __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할 수 있는 모듈을 정의해 주어야 한다.

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

# C:/doit/game/sound/__init__.py
__all__ = ['echo']

 

※ from game.sound.echo import *  __all__과 상관없이 무조건 import된다. 이렇게 __all__과 상관없이 무조건 import되는 경우는 from a.b.c import * 에서 from의 마지막 항목인 c가 모듈인 경우이다.

 

이를 실행하면 다음과 같다.

>>> from game.sound import *
>>> echo.echo_test()
echo

 

relative 패키지

graphic 디렉터리의 render.py 모듈이 sound 디렉터리의 echo.py 모듈을 사용하는 경우

# render.py
from game.sound.echo import echo_test
# from ..sound.echo import echo_test
def render_test():
    print ("render")
    echo_test()

.. 는 부모 디렉토리를 뜻하고 . 는 현재 디렉토리를 뜻한다.

-> 이러한 relative 접근자는 모듈 안에서만 사용이 가능하고, 파이썬 인터프리터 사용하면 "SystemError: cannot perform relative import" 오류가 난다 !

 

실행결과

>>> from game.graphic.render import render_test
>>> render_test()
render
echo

 

 

 

패키지에 대해서는 사용을 거의 안해봐서 잘 몰랐는데, 한 번 짚고 넘어가는 시간이 되어 너무 좋았다 😊

다음은 파이썬에서의 예외처리를 점프투 파이썬과 함께 알아보고자 한다.

 

'TIL > 코테개념_python' 카테고리의 다른 글

[python] 정규 표현식 시작하기 뿌시기  (0) 2021.01.07
[python] 예외 처리 뿌시기  (0) 2021.01.07
[python] 모듈 뿌시기  (0) 2021.01.07
[python] 클래스 뿌시기  (0) 2021.01.07
[python] 파일 읽고 쓰기  (0) 2021.01.07
Comments