Package

김상우·2022년 3월 22일

Python

목록 보기
11/14
post-thumbnail

완전 기초부터 시작하는 파이썬

Package

모듈은 전역변수, 함수, 클래스 등을 모아놓은 파일이라면, 패키지는 모듈을 디렉토리 형식으로 구조화 한 것이다.
패키지는 . 을 사용해 파이썬 모듈을 계층적으로 관리할 수 있게 해준다.

패키지 만들기

패키지는 모듈을 넣어둔 디렉토리가 패키지명이 된다.
패키지 내 각 디렉토리에는 __init__.py가 반드시 존재해야 한다.__init__.py는 내용이 비어있을 수도 있고, 패키지 내에 포함된 모듈의 정보를 제공하기도 한다.

  • 예시

    # 예시 : 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디렉토리를 생성하고 그 아래 기타 서브 디렉토리를 생성한다.
    그 후 각 디렉토리마다 __init__.py파일을 생성한다.

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

    위의 두개의 파일은 현재 sound 디렉토리에 위치한 상태이며 해당 모듈들을 import하는 방법은 다음과 같다

    # 방법 1
    import game.sound.echo
    
    print(game.sound.echo.echo_test())
    # 방법 2
    from game.sound import echo
    
    print(echo.echo_test())
    # 방법 3
    from game.sound.echo import echo_test
    
    print(echo_test())

    세가지 방법 모두 아래의 결과로 동일하다.

    echo

    단, 다음과 같은 방법으로 사용하는 것은 불가능하다.

    # 잘못된 방법 1
    import game
    
    print(game.sound.echo.echo_test())
    # 잘못된 방법 2
    import game.sound.echo.echo_test
    
    print()

    반드시 . 을 사용해 import a.b.c처럼 import 할 때 가장 마지막 항목인 c는 모듈이거나 패키지여야만 한다.

    잘못된 방법 1은 game 디렉토리의 모듈 또는 __init.py__에 정의한 것만 참조 가능하므로 잘못되었다.

    잘못된 방법 2은 import a.b.c의 c부분이 모듈이나 패키지가 아니므로 잘못되었다.

__init__.py의 용도

__init__.py파일은 해당 디렉토리가 패키지의 일부임을 알려주는 역할을 한다. 만약 패키지에 포함된 디렉토리에 __init__.py 파일이 없으면 패키지로 인식되지 않으며, 없는 상태에서 import 하게되면 다음과 같이 오류가 나타난다.

# __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 defiend

python 3.3 버전부터는 __init__.py가 없어도 패키지로 인식하지만 하위버전 호환성을 위해 생성하는 것이 안전하다.

  • __all__
    특정 디렉토리의 모듈을 *을 사용하여 import 할 때는 __init__.py파일에 __all__변수를 설정하고 호출할 수 있는 모듈을 정의해줘야 한다.
# game/sound/__init__.py

__all__ = ['echo']

위 파일의 의미는 sound 디렉토리에서 *기호를 사용하여 import할 경우 이곳에 정의된 echo모듈만 import된다.

파일수정 후 다시 수행하면 다음과 같이 작동하는 것을 확인할 수 있다.

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

relative 패키지

예시 구조의 graphic의 render.py모듈이 sound 디렉토리의 echo.py를 사용하고자 할때는 아래처럼 파일을 수정하면 사용할 수 있게 된다.

# render.py

from game.sound.echo import echo_test

def render_test()
	print("render")
    echo_test()

첫 번째 줄처럼 import를 하면 다음과 같이 정상작동하는 것을 볼 수 있다.

>>> from game.graphic.render import render_test()
>>> render_test()
rendeo
echo
profile
아침엔 운동하고 밤엔 잠을 잔다.

0개의 댓글