__name__ == "__main__"이라면 무엇을합니까?
질문
다음 코드를 감안할 때 __name__ == "__main__"인 경우는 무엇입니까?
# 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))
답변
짧은 답변
사용자가 의도하지 않은 경우 사용자가 실수로 스크립트를 호출하지 못하도록 보호하는 Goilerplate 코드입니다.다음은 스크립트에서 가드를 생략 할 때 몇 가지 일반적인 문제가 있습니다.
다른 스크립트 (예 : my_script_without_a_namepipt_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")
특별 변수
파이썬 인터프리터가 소스 파일을 읽으면 먼저 몇 가지 특수 변수를 정의합니다.이 경우 __name__ 변수를 걱정합니다.
모듈이 주 프로그램 인 경우
모듈 (소스 파일)을 주 프로그램으로 실행하는 경우, 예를 들어,
python foo.py
통역사는 __name__ 변수, 즉 __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 문에서 __name__ 변수, 즉 __name__ 변수에 이름을 지정합니다.
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"
모듈의 코드를 실행합니다
특수 변수가 설정된 후 인터프리터는 한 번에 하나의 명령문 인 모듈의 모든 코드를 실행합니다.코드 샘플을 사용하여 다른 윈도우를 열고이 설명과 함께 따르도록 할 수 있습니다.
언제나
It prints the string
"before import"
(without quotes).It loads the
math
module and assigns it to a variable calledmath
. This is equivalent to replacingimport math
with the following (note that__import__
is a low-level function in Python that takes a string and triggers the actual import):
# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
It prints the string
"before functionA"
.It executes the
def
block, creating a function object, then assigning that function object to a variable calledfunctionA
.It prints the string
"before functionB"
.It executes the second
def
block, creating another function object, then assigning it to a variable calledfunctionB
.It prints the string
"before __name__ guard"
.
모듈이 주 프로그램 인 경우에만
- If your module is the main program, then it will see that
__name__
was indeed set to"__main__"
and it calls the two functions, printing the strings"Function A"
and"Function B 10.0"
.
모듈이 다른 모듈을 가져올 때만
- (instead) If your module is not the main program but was imported by another one, then
__name__
will be"foo"
, not"__main__"
, and it'll skip the body of theif
statement.
언제나
- It will print the string
"after __name__ guard"
in both situations.
요약
요약하면 두 가지 경우에 인쇄 할 것입니다.
# 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를 제공합니다.
그 예를 넘어서, 파이썬에서 스크립트를 실행하는 것은 몇 가지 마법의 변수를 설정하고 스크립트를 가져 오는 것입니다."실행"스크립트는 스크립트 모듈을 가져 오는 부작용입니다.
생각할 거리
질문 : __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")
답변
스크립트가 파이썬 인터프리터에 대한 명령으로 전달하여 스크립트가 실행되면,
python myscript.py
들여 쓰기 수준 0에있는 모든 코드가 실행됩니다.정의 된 함수와 클래스는 잘 정의되었지만 코드가 실행되지 않습니다.다른 언어와 달리 자동으로 실행되는 main () 함수가 없습니다. main () 함수는 최상위 레벨의 모든 코드를 암시 적으로 암시 적으로합니다.
이 경우 최상위 코드는 anf 블록입니다.__name__은 현재 모듈의 이름으로 평가되는 기본 제공 변수입니다.그러나 모듈이 직접 실행되는 경우 (위의 myscript.py에서와 같이) 대신 __name__은 "__main__"문자열로 설정됩니다.따라서 스크립트가 직접 실행 중이거나 테스트를 통해 다른 것으로 가져 오는지 여부를 테스트 할 수 있습니다.
if __name__ == "__main__":
...
스크립트가 다른 모듈로 가져 오는 경우 다양한 기능 및 클래스 정의를 가져 와서 최상위 코드가 실행되지만 위의 IF 절의 코드의 코드는 조건으로 실행되지 않습니다.충족되지 않습니다.기본 예제에서 다음 두 스크립트를 고려하십시오.
# file one.py
def func():
print("func() in one.py")
print("top-level in one.py")
if __name__ == "__main__":
print("one.py is being run directly")
else:
print("one.py is being imported into another module")
# file two.py
import one
print("top-level in two.py")
one.func()
if __name__ == "__main__":
print("two.py is being run directly")
else:
print("two.py is being imported into another module")
이제 인터프리터를 AS를 호출하는 경우
python one.py
출력이 될 것입니다
top-level in one.py
one.py is being run directly
대신 2.py를 실행하면 :
python two.py
너는 얻는다
top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly
따라서 모듈이로드되면 __name__은 "__main__"대신 "하나"와 같습니다.
답변
__name__ 변수 (IMHO)에 대한 가장 간단한 설명은 다음과 같습니다.
다음 파일을 만듭니다.
# a.py
import b
그리고
# b.py
print "Hello World from %s!" % __name__
if __name__ == '__main__':
print "Hello World again from %s!" % __name__
실행중인이 출력을 얻을 수 있습니다.
$ python a.py
Hello World from b!
보시다시피 모듈을 가져올 때이 모듈에서 globals () [ '__ name__']를 모듈의 이름으로 설정합니다.또한 가져 오기시 모듈의 모든 코드가 실행 중입니다.IF 문이 FALSE로 평가 되므로이 부분은 실행되지 않습니다.
$ python b.py
Hello World from __main__!
Hello World again from __main__!
보시다시피 파일이 실행될 때 파이썬은이 파일에서 globals () [ '__ name__']을 "__main__"로 설정합니다.이번에는 if 문이 true로 평가되며 실행 중입니다.
답변
IF __name__ == "__main__"은 무엇입니까?
기본 사항을 설명하려면 다음을 수행하십시오.
전역 변수, __name__, 프로그램의 진입 점 인 모듈에서 '__main__'입니다.그렇지 않으면 모듈을 가져 오는 이름입니다. 따라서 모듈이 프로그램에 대한 진입 점 인 경우에만 코드가 실행됩니다. 모듈의 코드가 가져 오기에있는 코드 블록을 실행하지 않고도 모듈의 코드를 다른 모듈에서 가져올 수 있습니다.
왜 우리는 이것을 필요로합니까?
코드 개발 및 테스트
모듈로 사용하도록 설계된 Python 스크립트를 작성하고자합니다.
def do_important():
"""This function does something very important"""
이 함수 의이 호출을 하단에 추가하여 모듈을 테스트 할 수 있습니다.
do_important()
그리고 (명령 프롬프트에서) 실행 중입니다.
~$ python important.py
문제
그러나 모듈을 다른 스크립트로 가져 오려는 경우 :
import important
가져 오기에서 do_important 함수가 호출되므로 함수 호출, do_important (), 하단에 주석 처리 할 것입니다.
# do_important() # I must remember to uncomment to execute this!
그런 다음 테스트 함수 호출을 주석 처리했는지 여부를 기억해야합니다.그리고이 여분의 복잡성은 당신이 잊을 가능성이 있으므로 개발 과정을 더욱 번거롭게 만듭니다.
더 나은 방법
__name__ 변수는 파이썬 인터프리터가 현재 일어나는 곳이면 네임 스페이스를 가리 킵니다.
가져온 모듈 내에서 해당 모듈의 이름입니다.
그러나 기본 모듈 (또는 인터랙티브 파이썬 세션, 즉 인터프리터의 읽기, eval, print 루프 또는 repr) 내부에서 "__main__"에서 모든 것을 실행 중입니다.
따라서 실행하기 전에 확인하십시오 :
if __name__ == "__main__":
do_important()
위의 내용을 사용하면 코드가 기본 모듈로 실행 중이거나 의도적으로 다른 스크립트에서 호출 할 때만 실행됩니다.
더 좋은 방법
그러나 이것을 향상시키는 pythonic 방법이 있습니다.
이 비즈니스 프로세스를 모듈 외부에서 실행하려는 경우 어떻게해야합니까?
우리가 이와 같은 기능에서 개발하고 테스트하고 즉시 '__main__'에 대한 검사를 수행 할 때 우리가 연습하고자하는 코드를 넣으려면 다음을 수행하십시오.
def main():
"""business logic for when running this module as the primary one!"""
setup()
foo = do_important()
bar = do_even_more_important(foo)
for baz in bar:
do_super_important(baz)
teardown()
# Here's our payoff idiom!
if __name__ == '__main__':
main()
이제 모듈을 기본 모듈로 실행하면 모듈이 실행될 모듈 끝에 최종 기능이 있습니다.
모듈과 함수와 클래스를 주 함수를 실행하지 않고 다른 스크립트로 가져올 수 있으며 다른 '__main__'모듈에서 실행할 때 모듈 (및 함수 및 클래스)을 호출 할 수 있습니다.
import important
important.main()
이 관용구는 __main__ 모듈에 대한 설명에서 파이썬 문서에서도 찾을 수 있습니다.그 텍스트는 다음과 같습니다.
이 모듈은 (그렇지 않으면 익명) 범위를 나타냅니다. 통역사의 주 프로그램이 실행됩니다 - 명령은에서 읽습니다. 표준 입력, 스크립트 파일 또는 대화식 프롬프트에서.그것 관용적 "조건부 스크립트"스탠자가있는이 환경입니다. 스크립트가 실행되도록합니다. __name__ == '__main__'인 경우 : 기본()
답변
__name__ == "__main__"가 Python MyScript.py와 같은 명령을 사용하여 스크립트가 실행될 때 실행되는 부분입니다.
답변
__name__ == "__main__"이라면 무엇을합니까?
__name__은 모든 네임 스페이스에 존재하는 전역 변수 (Python, Python, Lefully Module Level에서 실제로 의미)입니다.일반적으로 모듈의 이름입니다 (str 유형으로).
그러나 유일한 특별한 경우는 MyCode.py에서와 같이 실행중인 파이썬 프로세스에서 다음과 같습니다.
python mycode.py
그렇지 않으면 익명의 전역 네임 스페이스에 '__main__'값이 __name__에 할당됩니다.
따라서 최종 라인을 포함하여
if __name__ == '__main__':
main()
mycode.py 스크립트가 끝나면, 파이썬 프로세스에 의해 실행되는 기본 엔트리 포인트 모듈 인 경우,
스크립트의 고유하게 정의 된 주요 기능이 실행되도록합니다.
이 구성을 사용하는 또 다른 이점 : 코드를 다른 스크립트의 모듈로 가져온 다음 프로그램이 결정한 경우 주 함수를 실행할 수도 있습니다.
import mycode
# ... any amount of other code
mycode.main()
출처:https://stackoverflow.com/questions/419163/what-does-if-name-main-do
최근댓글