질문 : __name__ ==“__main__”:하면 어떻게됩니까?
다음 코드가 주어지면 if __name__ == "__main__":
do?
# Threading example
import time, thread
def myfunction(string, sleeptime, lock, *args):
while True:
lock.acquire()
time.sleep(sleeptime)
lock.release()
time.sleep(sleeptime)
if __name__ == "__main__":
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
답변
사용자가 의도하지 않았을 때 실수로 스크립트를 호출하지 못하도록 보호하는 상용구 코드입니다. 다음은 스크립트에서 가드가 생략 될 때 발생하는 몇 가지 일반적인 문제입니다.
- 가드리스 스크립트를 다른 스크립트 (예 :
import my_script_without_a_name_eq_main_guard
)로 가져 오면 두 번째 스크립트가 첫 번째 스크립트가 가져 오기시 실행되고 두 번째 스크립트의 명령 줄 인수를 사용하도록 트리거합니다. 이것은 거의 항상 실수입니다. - 가드리스 스크립트에 사용자 정의 클래스가 있고이를 피클 파일에 저장 한 경우 다른 스크립트에서이를 언 피클하면 이전 글 머리 기호에서 설명한 것과 동일한 문제가있는 가드리스 스크립트 가져 오기가 트리거됩니다.
이것이 왜 그리고 어떻게 중요한지 더 잘 이해하려면 파이썬이 스크립트를 초기화하는 방법과 이것이 모듈 가져 오기 메커니즘과 상호 작용하는 방법을 이해하기 위해 한 걸음 물러서야합니다.
Python 인터프리터는 소스 파일을 읽을 때마다 두 가지 작업을 수행합니다.
__name__
과 같은 몇 가지 특수 변수를 설정 한 다음- 파일에있는 모든 코드를 실행합니다.
이것이 어떻게 작동하는지 그리고 파이썬 스크립트에서 항상 볼 수 __name__ 검사에 대한 질문과 어떤 관련이 있는지 봅시다.
약간 다른 코드 샘플을 사용하여 가져 오기 및 스크립트가 작동하는 방식을 살펴 보겠습니다. foo.py
라는 파일에 있다고 가정합니다.
# Suppose this is foo.py.
print("before import")
import math
print("before functionA")
def functionA():
print("Function A")
print("before functionB")
def functionB():
print("Function B {}".format(math.sqrt(100)))
print("before __name__ guard")
if __name__ == '__main__':
functionA()
functionB()
print("after __name__ guard")
Python 인터프리터가 소스 파일을 읽을 때 먼저 몇 가지 특수 변수를 정의합니다. 이 경우 __name__
변수에 관심이 있습니다.
모듈이 메인 프로그램 인 경우
모듈 (소스 파일)을 기본 프로그램으로 실행하는 경우, 예 :
python foo.py
인터프리터는 하드 코딩 된 문자열 "__main__"
을 __name__
변수에 할당합니다. 즉
# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__"
모듈을 다른 사람이 가져 오는 경우
반면에 다른 모듈이 주 프로그램이고 모듈을 가져 왔다고 가정합니다. 이것은 메인 프로그램이나 메인 프로그램이 가져 오는 다른 모듈에 다음과 같은 명령문이 있다는 것을 의미합니다.
# Suppose this is in some other main program.
import foo
인터프리터는 foo.py
파일 (몇 가지 다른 변형 검색과 함께)을 검색하고 해당 모듈을 실행하기 전에 import 문에서 "foo"
__name__
변수에 할당합니다.
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"
특수 변수가 설정된 후 인터프리터는 모듈의 모든 코드를 한 번에 하나씩 실행합니다. 이 설명을 따라 할 수 있도록 코드 샘플 옆에 다른 창을 열 수 있습니다.
항상
"before import"
(따옴표없이) 문자열을 인쇄합니다.- 그것은로드
math
모듈과 변수라고에 할당math
.import math
를 다음으로 대체하는 것과 동일합니다__import__
는 문자열을 가져와 실제 가져 오기를 트리거하는 Python의 저수준 함수입니다).
# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
"before functionA"
문자열을 인쇄합니다.def
블록을 실행하고 함수 객체를 만든 다음 해당 함수 객체를functionA
라는 변수에 할당합니다."before functionB"
문자열을 인쇄합니다.- 두 번째
def
블록을 실행하여 다른 함수 객체를 만든 다음functionB
라는 변수에 할당합니다. "before __name__ guard"
문자열을 인쇄합니다.
모듈이 메인 프로그램 인 경우에만
다른 사용자가 모듈을 가져온 경우에만
항상
요약
요약하면 두 가지 경우에 인쇄되는 내용은 다음과 같습니다.
# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard
왜 누군가가 이것을 원하는지 당연히 궁금 할 것입니다. 글쎄, 때로는 다른 프로그램 및 / 또는 모듈에서 모듈로 사용할 수 있고 주 프로그램 자체로 실행할 수도 .py
파일을 작성하고 싶을 때가 있습니다. 예 :
- 모듈은 라이브러리이지만 일부 단위 테스트 또는 데모를 실행하는 스크립트 모드를 원합니다.
- 모듈은 기본 프로그램으로 만 사용되지만 일부 단위 테스트가 있으며 테스트 프레임 워크는
.py
파일을 가져오고 특수 테스트 기능을 실행하여 작동합니다. 모듈을 가져 오기 때문에 스크립트를 실행하고 싶지는 않습니다. - 모듈은 대부분 기본 프로그램으로 사용되지만 고급 사용자를위한 프로그래머 친화적 인 API도 제공합니다.
이러한 예제 외에도 Python에서 스크립트를 실행하는 것은 몇 가지 매직 변수를 설정하고 스크립트를 가져 오는 것뿐입니다. 스크립트를 "실행"하는 것은 스크립트의 모듈을 가져 오는 부작용입니다.
__name__
검사 블록을 여러 개 가질 수 있습니까? 답변 : 그렇게하는 것이 이상하지만 언어가 당신을 막을 수는 없습니다.foo2.py
있다고 가정합니다. 명령 줄에서python foo2.py
라고 말하면 어떻게 되나요? 왜?
# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def functionA():
print("a1")
from foo2 import functionB
print("a2")
functionB()
print("a3")
def functionB():
print("b")
print("t1")
if __name__ == "__main__":
print("m1")
functionA()
print("m2")
print("t2")
foo3.py
__name__
체크를 제거하면 어떻게되는지 알아 내십시오.
# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def functionA():
print("a1")
from foo3 import functionB
print("a2")
functionB()
print("a3")
def functionB():
print("b")
print("t1")
print("m1")
functionA()
print("m2")
print("t2")
- 스크립트로 사용하면 어떻게 되나요? 모듈로 가져올 때?
# Suppose this is in foo4.py
__name__ = "__main__"
def bar():
print("bar")
print("before __name__ guard")
if __name__ == "__main__":
bar()
print("after __name__ guard")
출처 : https://stackoverflow.com/questions/419163/what-does-if-name-main-do
'프로그래밍 언어 > C++' 카테고리의 다른 글
POSIX를 사용하여 C ++에서 명령을 실행하고 명령의 출력을 얻는 방법 (0) | 2021.07.06 |
---|---|
new를 사용하여 C ++에서 2차원 배열을 선언하는 방법 (0) | 2021.07.06 |
C ++에서 변수 데이터 타입을 출력 하는 법 (0) | 2021.07.01 |
정렬되지 않은 배열을 처리하는 것보다 정렬 된 배열을 처리하는 것이 더 빠른 이유 (0) | 2021.07.01 |
C ++ 코드 파일 확장자 .cc와 .cpp의 차이점 (0) | 2021.06.30 |