Quick Flow
def main() -> None:
print("run app")
if __name__ == "__main__":
main()if __name__ == "__main__":는 file을 script로 실행할 때만 entry function을 호출하고, import할 때는 실행 부작용을 막습니다. 재사용할 로직은 main()과 helper 함수에 두며, package 실행이 필요하면 python -m package 경로도 함께 설계합니다.
문법
기본형은 실행 함수와 main guard 두 줄로 보면 됩니다.
def main() -> None:
...
if __name__ == "__main__":
main()실행 분리
main guard는 "직접 실행"과 "import 시 평가"를 구분한다
Python 모듈은 import될 때 top-level 문장이 한 번 평가됩니다. 그래서 실행용 코드를 그냥 아래에 두면, 다른 모듈이 import할 때도 원치 않게 동작할 수 있습니다. main guard는 이 문제를 막습니다.
def helper():
return 1
if __name__ == "__main__":
print(helper())이 패턴 덕분에 같은 파일을 스크립트로도, 라이브러리 모듈로도 쓸 수 있습니다.
실행 맥락
__name__ 값은 실행 맥락을 알려 준다
직접 실행된 파일은 __name__ == "__main__"이 되고, import된 모듈은 자신의 모듈 이름을 가집니다. python -m package.module처럼 모듈 실행 방식이어도 실행 진입점에서는 __main__으로 동작합니다.
print(__name__)이 규칙이 main guard가 동작하는 기반입니다.
실행 로직은 main() 함수 안으로 넣는 편이 테스트와 재사용에 좋다
guard 안에 바로 긴 코드를 쓰기보다 main() 함수로 감싸면 테스트와 재사용이 쉬워집니다.
def main() -> None:
...
if __name__ == "__main__":
main()입력 파싱, 리턴 코드 처리, 예외 처리도 이 구조 위에서 정리하기 좋습니다.
구조 선택
main guard를 언제 두는가
| 상황 | 적합한 선택 |
|---|---|
| 스크립트 직접 실행 코드 분리 | main guard |
| import 시 부작용 방지 | if __name__ == "__main__": |
| 실행 로직 정리 | main() 함수 |
| 재사용 가능한 유틸 제공 | top-level 정의 + guard 분리 |
주의할 점
top-level에 실행 코드를 바로 두면 import만 해도 동작해 버립니다.
# ❌ import 시에도 실행됨
print("start app")
# ✅ 직접 실행될 때만 수행
if __name__ == "__main__":
print("start app")참고 링크
2 sources