Python module과 package 구조에 대해 이해하고, Python 코드에서 자주 보이는 __init__py와 __main__.py의 의미를 정리한 포스트입니다. 😴
참고자료 - 점프 투 파이썬: 패키지
패키지(Package)는 Python 모듈이 어떤 계층을 가지고 모여있는 모듈의 집합입니다. 하나의 패키지 안에는 여러 개의 모듈이 들어있고, 각 모듈은 하나의 .py 파일입니다. A
라는 패키지 안에 들어있는 모듈 B.py
를 가리킬 때 A.B
로 나타냅니다.
참고 패키지 A
, 모듈 B.py
, 함수 C()
👉🏻 A.B.C
Flask같은 Python 코드를 보면 이런 코드를 자주 접하게 됩니다.
if __name__ == '__main__':
# ...
다음 예제 코드를 통해 \__name\__
과 \__main\__
에 대해 알아봅시다.
hello.py
print('hello 모듈 시작')
print('hello.py __name__:', __name__) # __name__ 변수 출력
print('hello 모듈 끝')
main.py
import hello # hello 모듈을 가져옴
print('main.py __name__:', __name__) # __name__ 변수 출력
실행
» python main.py
hello 모듈 시작
hello.py __name__: hello # 모듈로서 호출되었기 때문에 모듈의 이름이 출력됨!
hello 모듈 끝
main.py __name__: __main__ # main 코드로서 실행되었기 때문에 "__main__"이 출력됨!
따라서 어떤 모듈의 __name__
에 저장된 값이 모듈의 이름인지, 혹은 "__main__"
인지에 따라 모듈로 사용되었는지 혹은 직접 실행된 코드인지를 알 수 있습니다.
정리하면, Python은 C나 JAVA와는 달리 별도로 main 함수를 지정하지 않고, 어떤 .py 파일이든 프로젝트의 시작 함수가 될 수 있습니다. 그래서 시작 함수로 실행되었는지 여부를 확인하기 위해 __name__
을 검사하는 것이죠!
__init__.py
아래 예시와 같은 game이라는 이름의 Python 패키지가 있다고 가정합시다.
game/ # 루트 디렉터리
__init__.py
sound/ # 서브 디렉터리
__init__.py
echo.py
wav.py
graphic/ # 서브 디렉터리
__init__.py
screen.py
render.py
play/ # 서브 디렉터리
__init__.py
run.py
test.py
__init__.py
해당 디렉터리가 패키지의 일부임을 알려주는 역할을 합니다. 이 파일이 없는 디렉터리는 패키지에 포함이 안 됩니다. Python3.3 이후 버전부터는 __init__.py이 없어도 패키지로 인식하지만, 하위 버전과의 호환을 위해서는 이 파일을 생성하는 것이 안전합니다.
echo.py에 echo_test()라는 함수를 실행하기 위해 패키지 또는 모듈을 import하는 상황을 가정합시다.
# Python interpreter
>>> import game.sound.echo # 함수를 가지고 있는 패키지 영역을 import하여 함수를 사용
>>> game.sound.echo.echo_test() # OK
---
>>> from game.sound import echo # 모듈을 import하여 함수 사용
>>> echo.echo_test() # OK
---
>>> from game.sound.echo import echo_test # 함수를 직접 import
>>> echo_test() # OK
---
---
>>> import game # error!
>>> game.sound.echo.echo_test() # echo_test()는 game/__init__.py에 정의되어 있지 않음
---
>>> import game.sound.echo.echo_test # error!
# 도트(.) 연산자로 import하는 마지막 항목이 함수임!
import game
을 실행하면 game/
에 들어있는 __init__.py에 정의된 것만 참조할 수 있습니다. 또한, 도트(.) 연산자를 사용해 import하는 경우 가장 마지막 항목은 반드시 모듈이거나 패키지여야 합니다.
또, 아래처럼 특정
디렉터리의 모듈을 *
로 전부 import할 때에는 해당 디렉터리의 __init__.py에 __all__
변수를 선언하여 import하는 모듈을 정의해야 합니다.
game/sound/__init__.py에 __all__
이 정의되지 않은 경우
# Python interpreter
>>> from game.sound import *
>>> echo.echo_test() # error!
game/sound/__init__.py에 __all__
이 정의된 경우
# game/sound/__init__.py
__all__ = ['echo'] # sound라는 디렉터리에서 "*"에 포함될 모듈을 나열!
# Python interpreter
>>> from game.sound import *
>>> echo.echo_test() # OK
Python 프로젝트나 패키지, 혹은 코드에서 자주 등장하는 __init__.py와 "__main__"에 대해 살펴보았습니다. 프로그램의 시작점을 알려주는 변수가 "__main__", 패키지의 일부임을 알려주는 파일이 __init__.py입니다. 👾
As the rounds progressed, Jack’s initial nerves were replaced by confidence. He used a blend of basic strategy and his intuition to make https://winnerwolfcasino.com his decisions. To his delight, his efforts started paying off. He found himself winning hand after hand, each victory fueling his excitement. By the end of the night, Jack had not only enjoyed a thrilling experience but had also managed to double his initial deposit. His first foray into online gambling had turned out to be a memorable and profitable adventure.