[Python] __name__ == "__main__"은 무엇을합니까?



Answers

스크립트를 명령으로 전달하여 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__ 드되면 __name__"__main__" 대신 "one" 같습니다.

Question

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



가져올 수있는 모듈 뿐만 아니라 스크립트 로 파일을 사용할 수있게 만들 수 있습니다.

fibo.py (fibo.py 모듈)

# 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




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

__name__ 은 무엇입니까?

__name__ 은 DunderAlias입니다 - 모듈에서 액세스 할 수있는 전역 변수로 생각할 수 있으며 전역과 비슷한 방식으로 작동합니다.

이것은 ( type(__name__) ( <class 'str'> 만들어내는 type(__name__) 의해 표시되는 문자열이며, 파이썬 3파이썬 2 버전 모두에 대한 내장 표준입니다.

어디에:

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

통역사:

>>> print(__name__)
__main__
>>>

스크립트:

test_file.py :

print(__name__)

__main__ 결과

모듈 또는 패키지 :

somefile.py :

def somefunction():
    print(__name__)

test_file.py :

import somefile
somefile.somefunction()

일부 파일 결과

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

__name__ 이 메인 파일 (또는 프로그램) 인 곳은 항상 __main__ 반환하고 모듈 / 패키지이거나 다른 Python 스크립트에서 실행중인 파일이면 파일 이름을 반환합니다 에서 유래 한 곳입니다.

연습:

변수가 있으면 값 덮어 쓸 있음을 의미합니다 ( "할 수있다"는 뜻이 아닙니다). __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__' 지금 대답 if __name__ == '__main__' .

이제 __name__ 의 동작이 더 명확 해짐을 알 수 있습니다.

if 는 지정된 값이 true 인 경우 실행되는 코드 블록을 포함하는 흐름 제어 명령문입니다. 우리는 __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

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

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




대화식으로 Python을 실행하면 로컬 __name__ 변수에 __main__ 값이 할당됩니다. 마찬가지로 명령 행에서 파이썬 모듈을 가져 __name__ 않고 다른 모듈로 가져 오는 경우 __name__ 속성에는 실제 모듈 이름이 아닌 __main__ 값이 지정됩니다. 이런 식으로 모듈은 자신의 __name__ 값을보고 다른 프로그램에 대한 지원이나 명령 줄에서 실행되는 기본 응용 프로그램과 같은 사용 방법을 스스로 결정할 수 있습니다. 따라서 다음 관용구는 Python 모듈에서 매우 일반적입니다.

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.



시스템 (파이썬 인터프리터)이 소스 파일 (모듈)에 제공하는 많은 변수가 있습니다. 언제든지 원하는 값을 얻을 수 있으므로 __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 "과 같지 않으므로 다른 모듈이 호출하거나 가져 오는 경우 코드 블록이 실행되지 않습니다.

희망이 도움이됩니다.




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 인터프리터가있을 때마다 네임 스페이스를 가리 킵니다.

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

하지만 기본 모듈 (또는 대화 형 Python 세션, 즉 인터프리터의 읽기, 평가, 인쇄 루프 또는 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()



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

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

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



if __name__ == "__main__":
    main()

파이썬 스크립트의 __name__ 속성이 "__main__" 합니다. 즉, 프로그램 자체가 실행되면 속성은 __main__ 이되어 프로그램이 실행됩니다 (이 경우 main() 함수).

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




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

__name__ 은 모든 네임 스페이스에있는 전역 변수 (파이썬에서는 global은 모듈 수준 에서 실제로 의미 함)입니다. 일반적으로 모듈의 이름입니다 ( str 형식).

그러나 특별한 경우로서, mycode.py에서와 같이 어떤 Python 프로세스를 실행하든 :

python mycode.py

그렇지 않으면 익명의 전역 네임 스페이스에는 __name__'__main__' 값이 할당됩니다.

따라서 최종 라인을 포함 하여

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

스크립트의 고유하게 정의 된 main 기능이 실행됩니다.

이 구조를 사용하면 다음과 같은 이점이 있습니다. 코드를 다른 스크립트의 모듈로 가져온 다음 프로그램에서 결정할 때 main 함수를 실행할 수도 있습니다.

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



if name == ' main ':

우리는 __name__ == '__main__' 꽤 자주 봅니다.

모듈을 가져올 것인지 여부를 확인합니다.

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

modue의 이름을 출력하는 간단한 코드를 사용하여 무엇을하는지 봅시다.

# 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__



문제의 코드, "방법"의 메커니즘에 대해 많이 다른 점이 있지만 "왜"를 이해할 때까지 나에게 아무런 의미가 없습니다. 이는 특히 새로운 프로그래머에게 도움이됩니다.

"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 abimport ab . import 문은 import시 모듈을 즉시 실행하므로 ab 의 연산은 xy 의 나머지 부분보다 먼저 실행됩니다. ab 끝나면 xy 계속 진행됩니다.

해석기는 __name__ 으로 실행중인 스크립트를 추적합니다. 스크립트를 실행할 때 - 이름을 지정하지 않아도 - 인터프리터는이를 "__main__" 이라고 부르며 외부 스크립트를 실행 한 후에 반환되는 마스터 또는 '홈'스크립트로 만듭니다. 이 "__main__" 스크립트에서 호출 된 다른 스크립트에는 파일 이름이 __name__ (예 : __name__ == "ab.py" )으로 지정됩니다. 따라서 if __name__ == "__main__": 은 초기에 실행 된 'home'스크립트를 해석 / 파싱하는지 아니면 일시적으로 다른 (외부) 스크립트로 if __name__ == "__main__": 지를 판단하는 인터프리터의 테스트입니다. 이것은 프로그래머가 직접 실행하고 외부 적으로 호출하는 경우 스크립트가 다르게 동작하도록 유연성을 제공합니다.

위의 코드를 통해 단계별로 진행되는 내용을 이해하고 스크립트에 나타나는 순서와 줄을 먼저 살펴 보겠습니다. 함수 나 def 블록은 호출 될 때까지 아무 것도하지 않는다는 것을 기억하십시오. 자신에게 중얼 거리는 경우 통역사가 말할 수있는 것 :

  • xy.py를 'home'파일로 엽니 다. __name__ 변수에서 "__main__" 합니다.
  • __name__ == "ab.py" 파일 가져 오기 및 열기.
  • 오, 기능. 나는 그것을 기억할 것이다.
  • 좋아, a() 함수; 방금 배웠습니다. ' ab 파일의 함수 '를 출력합니다.
  • 파일의 끝; 다시 "__main__" !
  • 오, 기능. 나는 그것을 기억할 것이다.
  • 다른 것.
  • 함수 x() ; OK, 주변기기 작업 인쇄 : 다른 프로젝트에서 유용 할 수 있습니다 .
  • 이게 뭐야? if 문. 음, 조건이 충족되었습니다 ( __name__ 변수가 "__main__" 으로 설정되었습니다). 따라서 main() 함수를 입력하고 ' main function : this is the action is '을 인쇄합니다.

맨 아래의 두 줄은 "이 스크립트가 main 스크립트 또는 홈 스크립트 인 경우 main() "함수를 실행합니다. 그래서 def main(): 스크립트 상단 기능의 주요 흐름을 포함하는 block up을 볼 수 있습니다.

왜 이것을 구현합니까?

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

다시 말하지만 예외가있을 수 있지만 일반적으로 main() 은 대개 외부 적으로 호출되지 않습니다. 그래서 우리는 main() 호출하지 않으면 왜 스크립트를 호출할까요? 많은 사람들이 독립 실행 형 함수를 사용하여 스크립트를 구성하기 때문에 파일의 나머지 코드와 독립적으로 실행되도록 만들어졌습니다. 그런 다음 나중에 스크립트 본문의 다른 곳에서 호출됩니다. 어느 것이 나를 이리로 데려다 준다.

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

네, 맞습니다. 이러한 개별 함수 main() 함수 안에 포함되지 않은 인라인 스크립트에서 호출 할 수 있습니다. 내가 프로그래밍의 초기 학습 단계에 익숙하다면, 당신이 필요로하는 것을 정확히하는 인라인 스크립트를 만드는 것이고, 당신은 다시 그 조작이 필요하다면 다시 알아 내려고 할 것이다. 글쎄, 당신은 코드에 대한 내부 구조에 익숙하지 않다. 왜냐하면 빌드하기가 더 복잡하고 읽기가 직관적이지 않기 때문이다. 그러나 그것은 외부에서 호출 된 함수를 가질 수없는 스크립트입니다. 그렇지 않으면 즉시 변수를 계산하고 할당하기 시작합니다. 함수를 다시 사용하려고 시도하는 경우 새 스크립트는 기존 변수와 충분히 긴밀하게 관련되어있어 충돌하는 변수가있을 가능성이 있습니다.

독립 함수를 분리 할 때 이전 스크립트를 다른 스크립트로 호출하여 이전 작업을 다시 사용할 수 있습니다. 예를 들어, "example.py"는 "xy.py"에서 'x'함수를 사용하여 "xy.py"를 호출하고 x() 호출 할 수 있습니다. (아마도 주어진 텍스트 문자열의 3 번째 단어를 대문자로 만들거나 숫자 목록에서 숫자가 적은 배열을 만들어서 제곱하거나 3D 표면을 디졸브하는 등의 가능성이 있습니다.)

[제쳐두고, 이 스레드 에는 @kindall에 의한 대답 포함되어 있습니다.이 대답은 마침내 이해하는 데 도움이되었습니다. 불행히도 이것은 중복 된 것으로 표시되어 있습니다. 이것은 실수라고 생각합니다.]






Links