분명 로컬에서 실행시킬 때 잘되다가 배포할 때는 작동이 왜 안 되는지 궁금해서 찾아봤다.
if __name__ == '__main__':
먼저, 이 코드를 이해하는 것이 중요하다.
if __name__ == '__name__'
.py파일에는 __name__이라는 숨겨진 변수가 있다. 이 변수는 모듈의 이름을 가지고 있는 변수로 코드가 실행되고 있는. py파일의 이름을 가지고 있는 변수이다. 다음 두 파일이 있다고 해보자.
#app1.py
print("app1.py 이름 : ", __name__)
#app2.py
import app1
print("app2.py 이름 : ", __name__)
그리고 app2.py 파일을 실행시켰을 때 app1.py는 import 되고 자동으로 실행되므로 다음과 같이 출력된다.
#출력
app1.py 이름 : app1
app2.py 이름 : __main__
app2.py에서 실행해서 app2.py는 main이므로 __main__이라고 출력된다.
그런데 문제가 생긴다. 예를 들어 app1.py를 실행시키고 싶지는 않고, 그냥 모듈로서 사용하고 싶어서 app2.py에서 import 한 경우를 생각해 보자.
#app1.py
...
print("a")
...
#app2.py
import app1
...
print("b")
...
이 경우에서 app1.py는 모듈로서 사용하고 싶지만 즉, 원하는 출력은 "b"이지만, 파이썬 특성상 "a"와 "b" 둘 다 출력되게 된다. 따라서, 아래와 같이 __name__를 이용한 구문을 넣어주면 모듈이 import 되면서 실행되는 일을 막을 수 있다.
#app1.py
if __name__=="__main__":
print("a")
위의 코드를 설명하자면 app1.py에서의 __name__은 app1이므로 모듈을 불러올 때 모듈임을 인식할 수 있다.
정리하자면 if __name__ == "__main__"는 해당 구문이 사용된 파이썬 파일을 직접 실행했을 때만 코드를 실행하겠다는 의미이다.
flask에서 필요한 이유
github Flask 객체 생성 코드를 보면, Flask객체가 생성될 때 import_name을 이용하여 auto_find_instance_path를 호출하고,
def auto_find_instance_path(self) -> str:
"""Tries to locate the instance path if it was not provided to the
constructor of the application class. It will basically calculate
the path to a folder named ``instance`` next to your main file or
the package.
.. versionadded:: 0.8
"""
prefix, package_path = find_package(self.import_name)
if prefix is None:
return os.path.join(package_path, "instance")
return os.path.join(prefix, "var", f"{self.name}-instance")
해당 함수는 find_package함수를 호출하여 경로를 찾는데 find_package 함수에서 아래와 같은 코드를 찾을 수 있다.
if loader is None or root_mod_name == "__main__":
# import name is not found, or interactive/main module
return os.getcwd() #os.getcwd() : 현재 작업 경로 가져오기
즉, import_name이 __main__으로 넘어올 시 현재 경로를 반환한다는 것이다.
첫 번째 인자(import_name)의 리소스와 파일 시스템 때문에 사용된다고 한다.
root경로부터 모듈을 읽고 리소스, 템플릿들을 읽기 편하게 하기 위해서라고 한다.
이렇게 까지 깊게 안 가더라도, flask 문서에 실행한 서버가 현재 동작되는 유일한 서버라는 것을 보장하기 위해 필요하다고 써져 있긴 하다.
참고자료
https://flask-docs-kr.readthedocs.io/ko/latest/quickstart.html
https://blog.namthplayground.com/32
https://tibetsandfox.tistory.com/44
https://github.com/pallets/flask/blob/2.2.2/src/flask/app.py
'언어 > Python' 카테고리의 다른 글
[Python] pyenv로 파이썬 버전 관리 (0) | 2024.01.22 |
---|---|
Pandas.2 (0) | 2023.01.18 |
Pandas.1 (0) | 2023.01.15 |
[파이썬] 입력시간 초과 (0) | 2022.12.31 |