__main__ — 최상위 코드 환경

main — 최상위 코드 환경

파이썬에서 특별한 이름 __main__은 두 가지 중요한 구성 요소에 사용돼요.

  • 프로그램의 최상위 환경(top-level environment) 의 이름 — __name__ == '__main__' 표현식으로 확인할 수 있어요
  • 파이썬 패키지 안의 __main__.py 파일

이 두 메커니즘 모두 파이썬 모듈과 관련이 있고, 사용자가 어떻게 상호작용하는지와 서로 어떻게 상호작용하는지에 따라 달라져요. 모듈을 처음 접한다면 튜토리얼의 Modules 섹션을 먼저 보는 걸 추천해요.

출처: Python documentation

본문

__name__ == '__main__'

파이썬 모듈이나 패키지가 import되면 __name__은 모듈의 이름으로 설정돼요. 보통 .py 확장자를 뺀 파일 이름 자체예요.

>>> import configparser
>>> configparser.__name__
'configparser'

파일이 패키지의 일부라면 __name__에 부모 패키지 경로도 포함돼요.

>>> from concurrent.futures import process
>>> process.__name__
'concurrent.futures.process'

하지만 모듈이 최상위 코드 환경에서 실행되면 __name__은 문자열 '__main__'이 돼요.

"최상위 코드 환경"이란?

__main__은 최상위 코드가 실행되는 환경의 이름이에요. 최상위 코드는 프로그램이 필요로 하는 다른 모든 모듈을 import하는 첫 번째 사용자 지정 파이썬 모듈이에요. 가끔은 애플리케이션의 진입점(entry point)이라고도 불러요. 최상위 코드 환경이 될 수 있는 경우는 다음과 같아요.

  • 대화형 프롬프트의 스코프 (>>> __name__'__main__')
  • 인터프리터에 파일 인자로 전달된 파이썬 모듈 ($ python helloworld.py)
  • -m 인자로 전달된 모듈이나 패키지 ($ python -m tarfile)
  • 표준 입력에서 읽은 파이썬 코드 ($ echo "import this" | python)
  • -c 인자로 전달된 파이썬 코드 ($ python -c "import this")

이 모든 상황에서 최상위 모듈의 __name__'__main__'으로 설정돼요. 그래서 모듈은 자기 __name__을 확인해서 최상위 환경에서 실행 중인지 알 수 있어요. 이걸로 import 문에서 초기화되지 않을 때만 조건부로 코드를 실행하는 관용구를 만들 수 있어요.

if __name__ == '__main__':
    # Execute when the module is not initialized from an import statement.
    ...

관용적 사용 (Idiomatic Usage)

어떤 모듈은 커맨드라인 인자 파싱이나 표준 입력에서 데이터 읽기처럼 스크립트 전용 코드를 담고 있어요. 이런 모듈을 다른 모듈에서(예: 단위 테스트를 위해) import하면 스크립트 코드가 의도치 않게 함께 실행돼 버려요. 이때 if __name__ == '__main__' 블록이 유용해요. 이 블록 안의 코드는 모듈이 최상위 환경에서 실행될 때만 동작해요.

이 블록 안에는 가능한 한 적은 문장만 두는 게 코드 명확성과 정확성에 좋아요. 보통 main이라는 함수가 프로그램의 핵심 동작을 캡슐화해요.

# echo.py
import shlex
import sys
def echo(phrase: str) -> None:
   """A dummy wrapper around print."""
   print(phrase)
def main() -> int:
    """Echo the input arguments to standard output"""
    phrase = shlex.join(sys.argv)
    echo(phrase)
    return 0
if __name__ == '__main__':
    sys.exit(main())  # next section explains the use of sys.exit

모듈이 코드를 main 함수에 넣지 않고 if __name__ == '__main__' 블록에 직접 두면 phrase 변수가 모듈 전체의 전역이 돼요. 다른 함수가 의도치 않게 그 전역 변수를 쓰게 될 수 있어서 오류가 나기 쉬워요. main 함수는 이 문제를 해결해 줘요. 또 echo 함수만 따로 분리되어 다른 곳에서 import할 수 있다는 장점도 있어요.

패키징 고려사항 (Packaging Considerations)

main 함수는 콘솔 스크립트의 진입점(entry point)으로 지정해서 커맨드라인 도구를 만드는 데 자주 쓰여요. 그렇게 하면 pip가 템플릿 스크립트에 sys.exit(main()) 형태로 함수 호출을 넣어요. 이때 mainsys.exit()에 넘길 수 있는 값(보통 정수나 None)을 반환하길 기대해요.

특히 main 함수에서 문자열을 반환하면 주의해야 해요. sys.exit()는 문자열 인자를 실패 메시지로 해석해서 종료 코드가 1이 되고, 그 문자열은 sys.stderr에 쓰여요.

파이썬 패키지의 __main__.py

가장 흔히 __main__.py 파일은 패키지의 커맨드라인 인터페이스를 제공하는 데 사용돼요. 패키지가 -m 플래그로 커맨드라인에서 직접 호출되면 __main__.py가 실행돼요.

$ python -m bandclass

이때 __main__.py의 내용은 보통 if __name__ == '__main__' 블록으로 감싸지 않아요. 대신 짧게 유지하고 다른 모듈에서 실행할 함수를 import해요. 단, .zip 파일 루트에 있는 __main__.py에는 이 기법이 안 통하므로, 일관성을 위해 __name__ 검사가 없는 최소한의 __main__.py를 선호해요.

import __main__

파이썬 프로그램이 어떤 모듈로 시작됐든, 같은 프로그램 안에서 실행 중인 다른 모듈은 __main__ 모듈을 import해서 최상위 환경의 스코프(네임스페이스)에 접근할 수 있어요. 인터프리터 시작 시 빈 __main__ 모듈이 sys.modules에 삽입되고, 최상위 코드를 실행하면서 채워져요.

예를 들어 REPL에서 정의한 내용은 __main__ 스코프의 일부가 돼요. __main__ 스코프는 pdbrlcompleter의 구현에도 사용돼요.

참고: 이렇듯 __main__을 import하면 import 주기가 생길 수 있는데, 부분적으로 채워진 모듈이 sys.modules에 있으므로 파이썬이 그걸 넘겨줘요. 자세한 내용은 import system 참조의 "Special considerations for __main__"을 보세요.

더 알아보기 (Learn more)