Programming Language/Python

[Python] 18. 패키지(package)

lumana 2023. 11. 7. 02:27

패키지(package)


패키지란 무엇인가?


  • 패키지는 도트를 사용하여 파이썬 모듈을 계층적(디렉토리 구조)으로 관리할 수 있게 해줌

  • 모듈이름이 A.B인 경우에 A는 패키지 이름, B는 A 패키지의 모듈이 된다.

    game/
      __init__.py
      sound/
        __init__.py
        echo.py
        wave.py
      graphic/
        __init__.py
        screen.py
        render.py
      play/
        __init__.py
        run.py
        test.py
    • game, sound, graphic, play는 directory 이름
    • .py 파일은 모듈
    • game directory가 root directory임
    • sound, graphic, play는 sub directory임
  • 패키지 구조로 파이썬 프로그램을 만들면 공동작업이나 유지보수 등 여려면에서 유리

  • 패키지 구조로 모듈을 만들면 다른 모듈과 이름이 겹치더라도 더 안전하게 사용 가능

패키지 만들기


  • 위 예시처럼 디렉터리를 만들고, 각 디렉터리 마다 __init__.py 생성 하고 기타 파일 만들기

    game/
      __init__.py
      sound/
        __init__.py
        echo.py
        wave.py
      graphic/
        __init__.py
        screen.py
        render.py
      play/
        __init__.py
        run.py
        test.py
    
    # echo.py
    
    def echo_test():
        print("echo")
    
    # render.py
    
    def render_test():
        print("render")
  • echo 모듈 import 하여 실행하기

import game.sound.echo
game.sound.echo.echo_test()
  • echo 모듈이 있는 디렉터리까지 from... import 하여 실행

    from game.sound import echo
    echo.echo_test()
  • echo 모듈의 echo_test 함수를 직접 Import하여 실행

    from game.sound.echo import echo_test
    echo_test()
  • 루트 디렉터리만 import 하여 서브 디렉터리의 모듈 함수를 사용할 수 없다.

    • 루트 디렉터리에 있는 모듈 또는 __init__.py에 정의한 것만 참조할 수 있음
    # error occured
    import game
    game.sound.echo.echo_test()
  • 도트 연산자를 통해 import 할 때 (import a.b.c) 마지막 항목인 c는 반드시 모듈 또는 패키지여야 함

    # error occured
    import game.sound.echo.echo_test

__init__.py의 용도

  • 해당 디렉토리가 패키지의 일부임을 알려줌

  • __init__.py가 없으면 패키지로 인식하지 않는다.

  • example

    from game.sound import *
    echo.echo_test() # error
    • 에러가 발생한 이유 : sound 디렉토리의 모듈 *를 import할 때 import 할 수 있는 모듈을 알려줘야함.

      • __init__.py 파일에 __all__ 변수를 설정하고 import 할 수 있는 모듈을 정의해야 한다.

      • __all__ = ['echo', '추가로 더있다면 추가']

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

      • from game.sound.echo import *는 __all__과 상관 없이 import 됨.

relative 패키지

  • grpahic 패키지의 render.py 모듈에서 sound디렉토리의 echo.py 모듈을 사용하고 싶을 때

    # render.py
    from game.sound.echo import echo_test
    
    def render_test():
      print("render")
      echo_test()
  • 조금 더 relative하게 import 해보고 싶다면

    # render.py
    from ..sound.echo import echo_test
    • ..(relative한 접근자) 사용 : 부모 디렉터리 의미

      • graphic과 sound의 디렉토리의 depth가 같으므로 가능한 것

      • 모듈안에서만 사용해야 하고, 인터프리터에서는 절대 사용 X(에러 발생)

참조) Do it! 점프 투 파이썬 (박응용 지음)