__name__ ==“__main__”인 경우 어떻게합니까?


6060

다음 코드가 주어지면 무엇을 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))

있음 if __name__ == "__main__":블록 상태가 더 이상 사용되지 않습니다 / 파이썬 3까지로 폐기? 나는 그것을 진술하는 정보를 찾았습니다.
carloswm85

1
@ carloswm85 사실이 아닙니다.
Giorgos Myrianthous

답변:


6639

파이썬 인터프리터는 소스 파일을 읽을 때마다 다음 두 가지를 수행합니다.

  • 와 같은 몇 가지 특수 변수를 설정 한 __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 interpeter는 소스 파일을 읽을 때 먼저 몇 가지 특수 변수를 정의합니다. 이 경우 __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__변수로 이름 을 지정합니다.

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

모듈 코드 실행

특수 변수가 설정된 후 인터프리터는 모듈의 모든 코드를 한 번에 한 명령문 씩 실행합니다. 코드 샘플과 함께 측면에서 다른 창을 열어서이 설명을 따라갈 수 있습니다.

항상

  1. 문자열 "before import"을 따옴표없이 인쇄합니다 .

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

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

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

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

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

  5. 문자열을 인쇄합니다 "before __name__ guard".

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

  1. 모듈이 주 프로그램 인 경우 __name__실제로 설정되어 있음을 확인 "__main__"하고 문자열 "Function A"및을 인쇄하는 두 가지 함수를 호출합니다 "Function B 10.0".

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

  1. ( 대신 ) 모듈이 기본 프로그램이 아니지만 다른 프로그램에서 가져온 __name__경우 "foo", not "__main__"이 아니라 if명령문 본문을 건너 뜁니다 .

항상

  1. "after __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.

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")
  • 이제 __name__체크인 을 제거하면 어떻게 될지 알아 봅니다 foo3.py.
# Suppose this is foo3.py.

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")

14
호기심 : subprocess.run('foo_bar.py')파이썬 스크립트에서 실행하면 어떻게됩니까 ? cmd를 수동으로 입력 할 때 foo_bar__name__ = '__main__'같이 시작 한다고 가정합니다 foo_bar.py. 그 경우입니까? @MrFooz의 답변을 고려하면이 작업을 수행하고 내가 좋아하는 한 번에 많은 "기본"모듈을 갖는 데 아무런 문제가 없어야합니다. __name__값을 변경 하거나 여러 개의 독립적으로 인스턴스 (또는 서로 의해 생성 된 인스턴스 subprocess)가 서로 상호 작용하여 파이썬과의 상호 작용이 평소와 같이 작동해야합니다. 내가 뭔가를 그리워합니까?
hajef

12
@hajef 당신은 일이 어떻게 작동하는지에 대해 정확합니다 subprocess.run. 즉, 스크립트간에 코드를 공유하는 가장 좋은 방법은 모듈을 작성하고 스크립트를 서로 스크립트로 호출하는 대신 스크립트가 공유 모듈을 호출하도록하는 것입니다. subprocess.run대부분의 디버거가 프로세스 경계를 ​​뛰어 넘지 않기 때문에 호출 을 디버깅하기가 어렵습니다 . 추가 프로세스 등을 생성하고 파괴하기 위해 사소한 시스템 오버 헤드를 추가 할 수 있습니다.
Mr Fooz

4
foo2.py import functionB에서 무엇을 생각 섹션에 대한 음식에 대한 foo2.py 예제에서 의심이 있습니까? 내보기에 그것은 단지 수입은 functionB에서 foo2.py
user471651

1
@MrFooz 나는이 xD와 같은 것을하려고 의도하지 않았습니다. 이런 종류의 물건 주위에 마음을 포장. @ user471651 from foo2 import functionBfunctionB에서 foo2를 가져와야하는 이유는 무엇 입니까? 그것은 의미 론적 왜곡이다. from module import method모듈에서 메소드를 가져옵니다.
hajef 2019

2
코드를 가져올 수있는 모듈 중 하나는 multiprocessing특히 Windows에서이 테스트를 수행하는 것입니다.
Yann Vernier

1801

스크립트를 Python 인터프리터에 명령으로 전달하여 스크립트를 실행하면

python myscript.py

들여 쓰기 수준 0에있는 모든 코드가 실행됩니다. 정의 된 함수와 클래스는 잘 정의되어 있지만 해당 코드는 실행되지 않습니다. 다른 언어와 달리 main()자동으로 실행되는 main()기능은 없습니다. 이 기능은 암시 적으로 최상위 수준의 모든 코드입니다.

이 경우 최상위 코드는 if블록입니다. __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")

이제 인터프리터를 다음과 같이 호출하면

python one.py

출력은

top-level in one.py
one.py is being run directly

two.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

따라서 모듈 one이로드되면 대신에 __name__동일 "one"합니다 "__main__".


멋진 대답, 이것은 내 의견으로는 가장 분명한 대답이었습니다. +1!
TheTechRobo36414519

그것에 대해 생각하는 방식에 +1 : 첫 번째 들여 쓰기 된 줄은 첫 번째 줄에서 함수를 실행할 때까지 처음에만 실행됩니다
Elijah Mock

719

__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실행 중입니다.


513

무엇을 if __name__ == "__main__":합니까?

기본 사항을 설명하려면 다음을 수행하십시오.

  • __name__프로그램의 시작점 인 모듈 의 전역 변수 는 '__main__'입니다. 그렇지 않으면 모듈을 가져 오는 이름입니다.

  • 따라서 if블록 아래의 코드 는 모듈이 프로그램의 진입 점 인 경우에만 실행됩니다.

  • 가져 오기시 코드 블록을 실행하지 않고도 모듈의 코드를 다른 모듈에서 가져올 수 있습니다.


왜 이것이 필요한가요?

코드 개발 및 테스트

모듈로 사용하도록 설계된 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__파이썬 인터프리터는 순간에 될 일이 어디 네임 스페이스에 변수를 가리 킵니다.

가져온 모듈 내에서 해당 모듈의 이름입니다.

그러나 기본 모듈 (또는 대화 형 Python 세션, 즉 인터프리터의 Read, Eval, Print Loop 또는 REPL) 내에서 모든 것을 실행하고 "__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수 있으며 다른 '__main__'모듈 에서 실행할 때 모듈 (및 해당 함수와 클래스)을 호출 할 수도 있습니다.

import important
important.main()

이 관용구는 또한 파이썬 문서에서 __main__모듈 에 대한 설명에서 찾을 수 있습니다 . 그 내용은 다음과 같습니다.

이 모듈은 인터프리터의 기본 프로그램이 실행하는 (그렇지 않은 익명의) 범위를 나타냅니다. 명령은 표준 입력, 스크립트 파일 또는 대화식 프롬프트에서 읽습니다. 관용적 인 "조건부 스크립트"스탠자가 스크립트를 실행하는 환경은 다음과 같습니다.

if __name__ == '__main__':
    main()

125

if __name__ == "__main__"는 같은 명령을 사용하여 명령 줄에서 스크립트를 실행할 때 실행되는 부분입니다 python myscript.py.


2
왜 파일 않습니다 helloworld.py단지와 print("hello world")그것에는 명령을 실행할 수 python helloworld.py없음이 경우에도 if __name__ == "__main__"?
hi15

83

무엇을 if __name__ == "__main__":합니까?

__name__는 모든 네임 스페이스에 존재 하는 전역 변수 (Python에서 전역은 실제로 모듈 레벨을 의미 함 )입니다. 일반적으로 모듈 이름 ( str유형)입니다.

그러나 유일한 특별한 경우로, mycode.py에서와 같이 실행하는 모든 Python 프로세스에서 :

python mycode.py

그렇지 않으면 익명 글로벌 네임 스페이스의 값이 할당됩니다 '__main__'의로를 __name__.

따라서 마지막 줄을 포함 하여

if __name__ == '__main__':
    main()
  • mycode.py 스크립트 끝에서
  • 파이썬 프로세스에 의해 실행되는 기본 엔트리 포인트 모듈 인 경우

스크립트의 고유하게 정의 된 main함수가 실행됩니다.

이 구문을 사용하면 얻을 수있는 또 다른 이점 : 코드를 다른 스크립트에서 모듈로 가져 와서 프로그램이 결정할 때 주 함수를 실행할 수도 있습니다.

import mycode
# ... any amount of other code
mycode.main()

72

문제의 코드 메커니즘 인 "어떻게"에 대한 다양한 설명이 여기에 있지만 "왜"를 이해하기 전까지는 아무런 의미가 없습니다. 이것은 새로운 프로그래머에게 특히 유용합니다.

"ab.py"파일을 가져 오십시오 :

def a():
    print('A function in ab file');
a()

그리고 두 번째 파일 "xy.py":

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

이 코드는 실제로 무엇을하고 있습니까?

당신이 실행할 때 xy.py, 당신은 import ab. import 문은 가져 오기 즉시 모듈을 실행하므로 ab의 작업은 나머지 작업보다 먼저 실행 xy됩니다. 로 끝나면으로 ab계속 진행됩니다 xy.

인터프리터는로 실행중인 스크립트를 추적합니다 __name__. 스크립트의 이름에 관계없이 스크립트를 실행하면 인터프리터가이를 호출 "__main__"하여 외부 스크립트를 실행 한 후 반환되는 마스터 또는 '홈'스크립트로 만듭니다.

"__main__"스크립트 에서 호출 된 다른 스크립트 에는 파일 이름 __name__(예 :)이 지정됩니다 __name__ == "ab.py". 따라서이 줄 if __name__ == "__main__":은 처음 실행 된 '홈'스크립트를 해석 / 파싱하는지 또는 일시적으로 다른 (외부) 스크립트를 들여다보고 있는지 확인하기위한 통역사의 테스트입니다. 이를 통해 프로그래머가 스크립트를 직접 실행하거나 외부에서 호출하는 경우 다르게 동작하도록 유연성을 제공합니다.

들여 쓰기되지 않은 줄과 스크립트에 나타나는 순서에 중점을두고 위의 코드를 단계별로 살펴 보겠습니다. 함수 또는 def블록은 호출 될 때까지 자체적으로 아무것도하지 않는다는 것을 기억하십시오 . 통역사가 스스로에게 말을 걸었을 때의 말 :

  • xy.py를 'home'파일로여십시오. 변수 "__main__"에서 호출하십시오 __name__.
  • 로 파일을 가져오고 엽니 다 __name__ == "ab.py".
  • 아, 기능. 나는 그것을 기억할 것이다.
  • 좋아, 기능 a(); 방금 배웠습니다. ' ab 파일의 기능 '인쇄 중 .
  • 파일의 끝; 다시 "__main__"!
  • 아, 기능. 나는 그것을 기억할 것이다.
  • 다른 것.
  • 기능 x(); 좋아, ' 주변 작업 : 다른 프로젝트에서 유용 할 수 있습니다 '인쇄 .
  • 이게 뭐야? if문. 조건이 충족되었으므로 (변수 __name__가으로 설정 됨 "__main__") main()함수에 들어가서 ' 주요 기능 :이 위치는 작업 위치 '를 인쇄 하겠습니다 .

맨 아래 두 줄은 "이것이" "__main__"또는 "홈"스크립트 인 경우 main()" 라는 함수를 실행하십시오 . 그렇기 때문에 def main():스크립트 기능의 주요 흐름이 포함 된 블록 업 이 표시 됩니다.

왜 이것을 구현해야합니까?

수입 명세서에 대해 앞서 말한 것을 기억하십니까? 모듈을 가져 오면 모듈을 '인식'하고 추가 지시를 기다리는 것이 아니라 실제로 스크립트 내에 포함 된 모든 실행 가능한 작업을 실행합니다. 따라서 스크립트의 고기를 main()함수에 넣으면 효과적으로 격리되어 다른 스크립트로 가져올 때 즉시 실행되지 않도록 격리됩니다.

다시 한 번 예외가 있지만 일반적 main()으로 일반적으로 외부에서 호출되지 않는 것이 일반적입니다. 그래서 당신은 한 가지 더 궁금 할 것입니다 : 우리가 전화하지 않으면 main()왜 우리는 스크립트를 부르는 것입니까? 많은 사람들이 파일의 나머지 코드와 독립적으로 실행되도록 작성된 독립형 함수로 스크립트를 구성하기 때문입니다. 그런 다음 나중에 스크립트 본문의 다른 곳에서 호출됩니다. 어느 것이 나를 이끌어 줍니까?

그러나 코드는 그것없이 작동합니다

네 맞습니다. 이러한 개별 함수 함수 내에 포함되지 않은 인라인 스크립트에서 호출 할 수 있습니다 main(). 당신이 (필자의 초기 학습 단계에서) 당신이 필요로하는 것을 정확하게 수행하는 인라인 스크립트를 만드는 데 익숙하다면, 당신은 그 작업이 다시 필요할 때 다시 알아 내려고 노력할 것입니다. 글쎄, 당신은 코드에 대한 이런 종류의 내부 구조에 익숙하지 않습니다.

그러나 그것은 아마도 외부에서 호출되는 함수를 가질 수없는 스크립트 일 것입니다. 그렇다면 변수를 즉시 계산하고 할당하기 시작하기 때문입니다. 함수를 재사용하려고 할 때 새 스크립트가 이전 스크립트와 밀접하게 관련되어 변수가 충돌 할 가능성이 있습니다.

독립 기능을 분리하면 이전 작업을 다른 스크립트로 호출하여 이전 작업을 재사용 할 수 있습니다. 예를 들어, "example.py"는 "xy.py" x()에서 'x'함수를 사용하여 "xy.py"를 가져 와서 호출 할 수 있습니다. (어쩌면 주어진 텍스트 문자열의 세 번째 단어를 대문자로 사용하거나, 숫자 목록에서 NumPy 배열을 만들어 제곱하거나, 3D 표면을 비추는 것입니다. 가능성은 무한합니다.)

(여기서, 이 질문 에는 @kindall의 답변 포함되어있어 마침내 이해하는 데 도움이되었습니다. 이유는 방법이 아닌 이유입니다. 불행히도 이것은 실수라고 생각되는 복제본으로 표시되었습니다 .)


52

모듈 ( M.py) 에 특정 명령문이있는 경우 메인 (가져 오지 않은)으로 실행될 때 실행되기를 원합니다 if. 이 블록 아래에 해당 명령문 (테스트 케이스, 인쇄 명령문)을 배치 할 수 있습니다 .

기본적으로 (모듈을 메인으로 실행하고 가져올 때가 아닌) __name__변수는로 설정되며 "__main__"가져올 때 __name__변수는 다른 값을 얻습니다. 대부분 모듈 이름 ( 'M')입니다. 이는 모듈의 여러 변형을 함께 실행하고 특정 입력 및 출력 문을 분리하고 테스트 사례가있는 경우에 유용합니다.

간단히 말해이 ' if __name__ == "main"'블록을 사용 하면 모듈을 가져올 때 (확실한) 코드가 실행되지 않습니다.


43

간단히 말해, __name__스크립트가 기본 모듈로 실행되는지 아니면 가져온 모듈로 실행되는지를 정의하는 각 스크립트에 대해 정의 된 변수입니다.

우리가 두 개의 스크립트를 가지고 있다면;

#script1.py
print "Script 1's name: {}".format(__name__)

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

script1을 실행 한 결과는

Script 1's name: __main__

script2 실행 결과는 다음과 같습니다.

Script1's name is script1
Script 2's name: __main__

보시다시피 __name__어떤 코드가 '메인'모듈인지 알려주십시오. 코드를 작성하고 C / C ++에서와 같이 구조적 문제에 대해 걱정할 필요가 없기 때문에, 파일이 '주요'기능을 구현하지 않으면 실행 파일로 컴파일 할 수 없으며, 그런 다음 라이브러리로 사용할 수 없습니다.

훌륭한 기능을 수행하는 Python 스크립트를 작성하고 다른 목적에 유용한 함수의 보트로드를 구현한다고 가정 해보십시오. 그것들을 사용하고 싶다면 스크립트를 가져 와서 프로그램을 실행하지 않고 사용할 수 있습니다 (코드가 if __name__ == "__main__":컨텍스트 내에서만 실행되는 경우 ). C / C ++에서는 이러한 부분을 파일을 포함하는 별도의 모듈로 나누어야합니다. 아래 상황을 묘사하십시오.

C에서 복잡한 가져 오기

화살표는 가져 오기 링크입니다. 각각 이전 모듈 코드를 포함시키려는 세 개의 모듈에는 6 개의 파일 (구현 파일 계산)과 5 개의 링크가 있습니다. 라이브러리로 특별히 컴파일되지 않으면 다른 코드를 C 프로젝트에 포함시키기가 어렵습니다. 이제 파이썬으로 그림을 그려보십시오.

파이썬에서 우아한 임포트

모듈을 작성하고 누군가가 코드를 사용하려면 모듈을 가져 오면 __name__변수가 프로그램의 실행 가능 부분을 라이브러리 부분과 분리하는 데 도움이됩니다.


2
C / C ++ 일러스트레이션이 잘못되었습니다. 같은 단위 이름 ( file1 )의 3 배 입니다.
Wolf

40

보다 추상적 인 방법으로 답을 살펴 보자.

이 코드가 다음과 같다고 가정 해보십시오 x.py.

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

블록 A와 B는 실행 중일 때 실행 x.py됩니다.

그러나 다른 모듈을 실행할 때 블록 A (B는 아님)가 실행됩니다 ( y.py예 : x.py가져 오기 및 코드가 함수에서 x.py호출되는 경우 y.py)


1
게시물을 수정할 수 없습니다 (변경이 필요한 경우 최소 6 자). 14 행은 'x.py'가 아닌 'xy'입니다.
항상 학습

35

파이썬을 대화식으로 실행하면 로컬 __name__변수에 값이 할당됩니다 __main__. 마찬가지로, 다른 모듈로 가져 오는 대신 명령 줄에서 Python 모듈을 실행할 때 __name__속성에 모듈 __main__의 실제 이름이 아닌 값이 할당됩니다 . 이런 방식으로 모듈은 __name__다른 프로그램을 지원하거나 명령 줄에서 실행되는 주 응용 프로그램으로 사용되는지 여부를 자체적으로 파악하여 자신이 사용중인 방법을 결정할 수 있습니다. 따라서 다음 관용구는 파이썬 모듈에서 매우 일반적입니다.

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

34

치다:

if __name__ == "__main__":
    main()

__name__Python 스크립트 의 속성이 인지 확인합니다 "__main__". 즉, 프로그램 자체가 실행되면 속성이 __main__이므로 프로그램이 실행됩니다 (이 경우 main()함수).

그러나 파이썬 스크립트를 모듈에서 사용하는 경우 if명령문 외부의 모든 코드 가 실행되므로 if \__name__ == "\__main__"프로그램이 모듈로 사용되는지 여부를 확인하기 위해 사용되므로 코드를 실행할지 여부를 결정합니다.


야광 답변 +1을 작성하는 것이 너무 오랜 시간 인 것 같습니다
snr

27

그것에 대해 설명하기 전에 if __name__ == '__main__'무엇이 무엇인지 이해하는 __name__것이 중요합니다 .

무엇입니까 __name__?

__name__A는 DunderAlias은 -와 비슷한 방식으로 글로벌 (모듈에서 액세스) 변수와 작품으로 간주 할 수 있습니다 global.

type(__name__)(yielding <class 'str'>) 으로 표시되는 문자열 (위에서 언급 한 것처럼 전역 )이며 Python 3Python 2 버전 모두에 대한 기본 제공 표준입니다 .

어디:

스크립트에서만 사용할 수있을뿐만 아니라 인터프리터와 모듈 / 패키지에서도 찾을 수 있습니다.

통역사:

>>> print(__name__)
__main__
>>>

스크립트:

test_file.py :

print(__name__)

를 야기하는 __main__

모듈 또는 패키지 :

somefile.py :

def somefunction():
    print(__name__)

test_file.py :

import somefile
somefile.somefunction()

를 야기하는 somefile

패키지 또는 모듈에서 사용될 때 __name__파일 이름을 사용합니다. 실제 모듈 또는 패키지 경로의 경로는 제공되지 않지만이 __file__를 허용 하는 자체 DunderAlias 가 있습니다.

당신은 어디에, 볼 수 __name__는 주 파일이고, (또는 프로그램)됩니다 항상 반환 __main__, 그것은 다른 파이썬 스크립트 떨어져 실행하는 모듈 / 패키지 또는 아무것도 경우, 파일의 이름을 반환 곳을 에서 유래했습니다.

연습:

변수는 값 덮어 쓸 있음을 의미하고 ( "can"은 "should"를 의미하지 않음) 값을 덮어 쓰면 __name__가독성이 떨어집니다. 어떤 이유로 든 그렇게하지 마십시오. 변수가 필요한 경우 새 변수를 정의하십시오.

항상의 값이 있다고 가정 __name____main__또는 파일의 이름입니다. 이 기본값을 다시 변경하면 더 많은 혼란이 발생하여 더 나은 결과를 얻을 수 있습니다.

예:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

일반적으로 if __name__ == '__main__'스크립트 를 포함하는 것이 좋습니다 .

이제 대답합니다 if __name__ == '__main__':

이제 우리는 __name__사물 의 행동 이 더 명확 해짐을 알고 있습니다 :

if소정 값이 참인 경우 실행하는 코드 블록을 포함하는 유동 제어 문이다. 가져온 파일 이름이나 파일 이름 을 __name__사용할 수 있음을 확인했습니다 __main__.

이는 __name__같으면 __main__파일이 기본 파일이어야하며 스크립트로 가져온 모듈이나 패키지가 아니라 실제로 실행 중이거나 인터프리터 여야합니다.

실제로 __name__값을 취하면 __main__해당 코드 블록에있는 모든 것이 실행됩니다.

이것은 실행중인 파일이 기본 파일 (또는 인터프리터에서 직접 실행중인 경우)이면 해당 조건을 실행해야 함을 알려줍니다. 패키지 인 경우 패키지가 아니어야하며 값은이 아닙니다 __main__.

모듈 :

__name__ 모듈에서 모듈의 이름을 정의하는 데 사용될 수도 있습니다

변형 :

다른 덜 일반적이지만 유용한 작업을 수행하는 것도 가능합니다 __name__.

파일이 모듈 또는 패키지 인 경우에만 실행 :

if __name__ != '__main__':
    # Do some useful things 

파일이 기본 파일 인 경우 하나의 조건을 실행하고 그렇지 않은 경우 다른 조건을 실행하십시오.

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

또한 라이브러리를 정교하게 사용하지 않고도 패키지 및 모듈에서 실행 가능한 도움말 기능 / 유틸리티를 제공하는 데 사용할 수 있습니다.

또한 명령 줄에서 모듈을 기본 스크립트로 실행할 수 있으므로 매우 유용 할 수 있습니다.


25

깊이 있고 간단한 단어로 답을 나누는 것이 가장 좋습니다.

__name__: 파이썬의 모든 모듈에는이라는 특별한 속성이 __name__있습니다. 모듈 이름을 리턴하는 내장 변수입니다.

__main__: 다른 프로그래밍 언어와 마찬가지로 Python에도 실행 진입 점, 즉 main이 있습니다. '__main__' 최상위 코드가 실행되는 범위의 이름입니다 . 기본적으로 Python 모듈을 사용하는 두 가지 방법이 있습니다. 직접 스크립트로 실행하거나 가져옵니다. 모듈이 스크립트로 실행되면로 __name__설정됩니다 __main__.

따라서 __name__속성 값은 __main__모듈이 기본 프로그램으로 실행될 때로 설정됩니다 . 그렇지 않으면의 값은 __name__ 모듈 이름을 포함하도록 설정됩니다.


23

명령 행에서 Python 파일을 호출 할 때 특히 유용합니다. 일반적으로 "main ()"함수를 호출하거나 명령 줄 인수 처리와 같은 다른 적절한 시작 코드를 실행하는 데 사용됩니다.

여러 가지 방법으로 쓸 수 있습니다. 다른 것은 :

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

나는 이것을 프로덕션 코드에서 사용해야한다고 말하지는 않지만에 대해 "매직적인"것이 없음을 보여줍니다 if __name__ == '__main__'. 파이썬 파일에서 주요 함수를 호출하는 좋은 규칙입니다.


7
나는 당신이 1) 부작용에 의존하고 2) 학대를 할 때이 나쁜 형태를 고려할 것 and입니다. and두 부울 명령문이 모두 참인지 확인하는 데 사용됩니다. 당신의 결과에 관심이 아니에요 이후 and, if문은 더 명확하게 당신의 의도를 전달합니다.
jpmc26

8
흐름 제어 메커니즘으로 부울 연산자의 단락 동작을 악용하는 것이 나쁜지 아닌지에 대한 질문을 제외하고는 더 큰 문제는 이것이 전혀 질문에 대답하지 못한다는 것 입니다.
Mark Amery

@MarkAmery haha, sheshe, 이제 그렇습니다. 😊
Falken 교수 계약은

19

시스템 (Python 인터프리터)이 소스 파일 (모듈)에 제공하는 여러 변수가 있습니다. 언제든지 원하는 값을 얻을 수 있으므로 __name__ 변수 / 속성 에 초점을 두도록하겠습니다 .

파이썬은 소스 코드 파일을로드 할 때, 그 안에있는 모든 코드를 실행합니다. (파일에 정의 된 모든 메소드와 함수를 호출하지는 않지만 정의합니다.)

인터프리터는 소스 코드 파일을 실행하기 전에 해당 파일에 대한 몇 가지 특수 변수를 정의합니다. __name__ 은 파이썬이 각 소스 코드 파일에 대해 자동으로 정의하는 특수 변수 중 하나입니다.

Python이이 소스 코드 파일을 기본 프로그램 (예 : 실행 파일)으로로드하는 경우이 파일의 특수 __name__ 변수가 "__main__" 값을 갖도록 설정합니다. .

다른 모듈에서 가져 오면 __name__ 이 해당 모듈의 이름으로 설정됩니다.

따라서 일부 예에서는 다음과 같습니다.

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))

코드 블록은 다음을 의미합니다.

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

모듈을 직접 실행할 때만 실행됩니다. __name__ 의 값이 해당 특정 인스턴스의 " main " 과 같지 않기 때문에 다른 모듈이 호출 / 가져 오는 경우 코드 블록이 실행 되지 않습니다 .

이것이 도움이되기를 바랍니다.


17

if __name__ == "__main__": 기본적으로 최상위 스크립트 환경이며, ( '먼저 실행되는 우선 순위가 가장 높습니다') 인터프리터를 지정합니다.

'__main__'최상위 코드가 실행되는 범위의 이름입니다. 모듈 은 표준 입력, 스크립트 또는 대화식 프롬프트에서 읽을 때와 __name__동일하게 설정 '__main__'됩니다.

if __name__ == "__main__":
    # Execute only if run as a script
    main()

17

이 페이지의 답변 전체에서 많은 것을 읽었습니다. 나는 당신이 그 사실을 알고 있다면 그 대답을 확실히 이해할 것입니다. 그렇지 않으면 여전히 혼란 스럽습니다.

간단히 말해 몇 가지 사항을 알아야합니다.

  1. import a action은 실제로 "a"에서 실행될 수있는 모든 것을 실행합니다.

  2. 지점 1 때문에 가져올 때 모든 항목이 "a"로 실행되는 것을 원하지 않을 수 있습니다.

  3. 포인트 2의 문제를 해결하기 위해 파이썬은 조건 검사를 할 수 있습니다

  4. __name__모든 .py모듈 에서 내재 된 변수입니다 . 때 a.py가져,의 값 __name__a.py모듈은 파일 이름 "으로 설정 a"; 경우에 a.py"직접 실행하여 python a.py,"어떤 수단 a.py의 엔트리 포인트를하고, 다음의 값 __name__a.py모듈은 문자열로 설정된__main__

  5. 파이썬 __name__이 각 모듈에 대한 변수 를 설정하는 메커니즘에 따라 포인트 3을 얻는 방법을 알고 있습니까? 대답은 매우 쉽습니다. if 조건을 넣으십시오 : if __name__ == "__main__": ...; __name__ == "a"기능적 필요에 따라 넣을 수도 있습니다

파이썬이 특별한 점은 포인트 4입니다! 나머지는 기본 논리입니다.


1
예, 포인트 1은 이해하는 데 필수적입니다. 이를 통해이 메커니즘의 필요성이 분명해집니다.
Eureka

16

치다:

print __name__

위의 출력은 __main__입니다.

if __name__ == "__main__":
  print "direct method"

위의 내용은 true이며 "direct method"를 인쇄합니다 . 이 클래스를 다른 클래스로 가져온 경우 가져 오는 동안 설정되어 있기 때문에 "직접 메소드"를 인쇄하지 않는다고 가정하십시오 __name__ equal to "first model name".


14

가져 오기 가능한 모듈 뿐만 아니라 스크립트 로 파일을 사용할 수 있습니다 .

fibo.py (라는 모듈 fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

참조 : https://docs.python.org/3.5/tutorial/modules.html


14

대한 이유

if __name__ == "__main__":
    main()

코드를 직접 가져 와서 발생할 수있는 가져 오기 잠금 문제 를 피하기위한 것 입니다. 파일이 직접 호출 된 경우 실행 하려고 하지만 ( 이 경우) 코드를 가져온 경우 가져 오기 프로그램은 가져 오기 잠금 문제를 피하기 위해 실제 기본 모듈에서 코드를 입력해야합니다.main()__name__ == "__main__"

부작용은 여러 진입 점을 지원하는 방법에 자동으로 로그온한다는 것입니다. main()진입 점으로 사용하여 프로그램을 실행할 수 있지만 반드시 할 필요는 없습니다 . 하지만 setup.py예상하는 main()다른 도구는 대체 진입 점을 사용합니다. 예를 들어, 파일을 gunicorn프로세스 로 실행하려면 a app()대신 함수 를 정의 하십시오 main(). 단지와 마찬가지로 setup.py, gunicorn당신은 그것을 (때문에 수입 잠금 문제로) 수입되는 동안은 아무것도하지 않습니다하지 않도록 코드를 가져옵니다.


3
가져 오기 잠금 에 대해 배우는 것이 좋습니다 . [...] 부분을 ​​조금 더 설명 하는 방법론에 사인을 설명해 주 시겠습니까?
Wolf

1
@ 울프 : 물론입니다. 여러 진입 점 방법론에 대한 몇 가지 문장을 추가했습니다.
personal_cloud

11

이 답변은 Python을 배우는 Java 프로그래머를위한 것입니다. 모든 Java 파일에는 일반적으로 하나의 공용 클래스가 포함됩니다. 해당 클래스를 두 가지 방법으로 사용할 수 있습니다.

  1. 다른 파일에서 클래스를 호출하십시오. 호출 프로그램에서 가져 오기만하면됩니다.

  2. 테스트 목적으로 수업을 단독으로 실행하십시오.

후자의 경우 클래스에는 public static void main () 메서드가 포함되어야합니다. 파이썬에서이 목적은 전역 적으로 정의 된 라벨에 의해 제공됩니다 '__main__'.


11

아래 코드 if __name__ == '__main__': 는 모듈이 스크립트로 호출 된 경우에만 실행됩니다 .

예를 들어 다음 모듈을 고려하십시오 my_test_module.py.

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

첫 번째 가능성 : my_test_module.py다른 모듈로 가져 오기

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

이제 호출하면 main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

최상위 print()문만 my_test_module실행됩니다.


두 번째 가능성 : my_test_module.py스크립트로 호출

이제 my_test_module.pyPython 스크립트로 실행하면 두 print()명령문이 모두 실행됩니다.

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

10

파이썬의 모든 모듈에는이라는 속성이 __name__있습니다. __name__ attribute 의 값은 __main__ 모듈이 다음과 같이 직접 실행될 때 python my_module.py입니다. 그렇지 않으면 (말할 때와 같이 import my_module)의 값은 __name__ 모듈의 이름입니다.

간단히 설명하는 작은 예입니다.

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

우리는 이것을 다음과 같이 직접 실행할 수 있습니다

python test.py  

산출

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

이제 다른 스크립트에서 위의 스크립트를 호출한다고 가정 해보십시오.

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

이것을 실행할 때

python external_calling.py

산출

42
I am inside hello_world
test

따라서 위의 설명은 다른 스크립트에서 테스트를 호출 할 때 루프 __name__test.py이 실행되지 않는다는 자체 설명입니다 .


6

이 .py 파일을 다른 .py 파일로 가져 오면 "if 문"아래의 코드가 실행되지 않습니다.

이 .py가 python this_py.py쉘에서 실행 되거나 Windows에서 두 번 클릭 된 경우. "if 문"아래의 코드가 실행됩니다.

일반적으로 테스트 용으로 작성되었습니다.


6

파이썬 인터프리터가 특정 모듈을 실행 중이면 __name__전역 변수에 값이 있습니다."__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

이 스크립트 인쇄를 실행하면 나를 볼 수 있습니다

이 파일을 파일 B로 가져 와서 파일 B를 실행하면 파일 A if __name__ == "__main__"에서 거짓이되어 인쇄됩니다 .


5

모든 답변은 기능을 거의 설명했습니다. 그러나 개념을 더 명확하게 정리하는 데 도움이 될 사용법의 한 가지 예를 제공하겠습니다.

a.py와 b.py라는 두 개의 Python 파일이 있다고 가정하십시오. 이제 a.py는 b.py를 가져옵니다. "import b.py"코드가 먼저 실행되는 a.py 파일을 실행합니다. 나머지 a.py 코드가 실행되기 전에 b.py 파일의 코드가 완전히 실행되어야합니다.

b.py 코드에는 해당 파일 b.py 전용 코드가 있으며 b.py 파일을 가져온 다른 파일 (b.py 파일 이외)은 원하지 않습니다.

이것이 바로이 코드 라인이 확인하는 것입니다. 이 파일이 코드를 실행하는 기본 파일 (즉, b.py) 인 경우 (이 경우에는 실행되지 않는 (a.py는 기본 파일)) 코드 만 실행됩니다.


4

a.py 파일을 만듭니다 .

print(__name__) # It will print out __main__

__name____main__파일이 기본 파일임을 표시하는 파일을 직접 실행할 때마다 항상 같습니다 .

동일한 디렉토리에 다른 파일 b.py를 작성하십시오 .

import a  # Prints a

그것을 실행하십시오. 가져온 파일의 이름을 인쇄 합니다 .

따라서 동일한 파일의 두 가지 동작 을 보여주기 위해 일반적으로 사용되는 트릭입니다.

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

4

만약 이름 == ' 주요 '

우리는 __name__ == '__main__':꽤 자주 본다 .

모듈을 가져오고 있는지 확인합니다.

즉, if블록 내의 코드는 코드가 직접 실행될 때만 실행됩니다. 여기서 directly의미 not imported합니다.

모듈 이름을 인쇄하는 간단한 코드를 사용하여 수행하는 작업을 살펴 ​​보겠습니다.

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

를 통해 코드를 직접 실행하면 python test.py모듈 이름은 __main__다음과 같습니다.

call test()
test module name=__main__

4

간단히 말하면 C 프로그래밍 언어 의 main함수 와 같이 파일을 실행하는 진입 점 입니다.


8
이 답변은 영업 이익 (또는 비슷한 질문을 가진 사용자가)에 모두 익숙한 가정합니다 C 엔트리 포인트가 무엇인지 알고있다.
arredond

1
이 답변은 또한 if __name__ == "__main__"블록 전에 부작용이없는 정의 이외의 코드가 발생하지 않는다고 가정합니다 . 기술적으로 실행되는 스크립트의 최상위는 프로그램의 진입 점입니다.
Charlie Harding
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.