Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

후레임의 프로그래밍

__name__ ==“__main__”:하면 어떻게됩니까? 본문

스택오버플로우(Stack Overflow)

__name__ ==“__main__”:하면 어떻게됩니까?

후레임 2020. 10. 26. 13:10
질문

 

다음 코드에서 if __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))



답변

Python 인터프리터는 소스 파일을 읽을 때마다 두 가지 작업을 수행합니다.

  • __ name __과 같은 몇 가지 특수 변수를 설정 한 다음

  • 파일에 있는 모든 코드를 실행합니다.

이 방식이 어떻게 작동하며 Python 스크립트에서 항상 볼 수있는 __ 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파일 (몇 가지 다른 변형 검색과 함께)을 검색하고 해당 모듈을 실행하기 전에 foo "라는 이름을 할당합니다. import 문에서 __ name __변수로의 code>, 즉

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

모듈 코드 실행

특수 변수가 설정되면 인터프리터는 모듈의 모든 코드를 한 번에 하나씩 실행합니다. 이 설명을 따라 할 수 있도록 코드 샘플 옆에 다른 창을 열 수 있습니다.

항상

  1. 가져 오기 전에 "문자열을 인쇄합니다 (따옴표없이).

  2. math모듈을로드하고 math라는 변수에 할당합니다. 이는 import math를 다음으로 대체하는 것과 같습니다 (__ import __는 문자열을 가져와 실제 가져 오기를 트리거하는 Python의 저수준 함수입니다).</p >

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. before function문자열을 인쇄합니다.

  2. def블록을 실행하여 함수 개체를 만든 다음 해당 함수 개체를 functionA라는 변수에 할당합니다.

  3. before function문자열을 인쇄합니다.

  4. 두 번째 def블록을 실행하여 다른 함수 개체를 만든 다음 functionB라는 변수에 할당합니다.

  5. __ name__ guard앞에 문자열을 인쇄합니다.

모듈이 기본 프로그램 인 경우에만

  1. 모듈이 주 프로그램 인 경우 __ name __이 실제로 __ main __로 설정되어 있고 두 함수를 호출하여 문자열을 인쇄합니다. Function A "Function B 10.0".

다른 사람이 모듈을 가져온 경우에만

  1. (대신) 모듈이 기본 프로그램이 아니지만 다른 프로그램에서 가져온 경우 __ name __은 (는) foo가됩니다. __ main __이며 if문의 본문을 건너 뜁니다.

항상

  1. 두 경우 모두 __ 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