programing

__main__py가 뭐죠?

nicescript 2022. 10. 10. 20:32
반응형

__main__py가 뭐죠?

이 뭐죠?__main__.py파일에 어떤 종류의 코드를 넣어야 하는지, 언제 넣어야 하는지.

Python 프로그램은 명령줄에서 .py 파일의 이름을 지정하여 실행되는 경우가 많습니다.

$ python my_program.py

또한 코드가 가득 찬 디렉토리 또는 zip 파일을 생성하여__main__.py그런 다음 명령줄에 디렉토리 또는 zip 파일의 이름을 지정하기만 하면 다음 명령을 실행할 수 있습니다.__main__.py자동:

$ python my_program_dir
$ python my_program.zip
# Or, if the program is accessible as a module
$ python -m my_program

이러한 방법으로 애플리케이션을 실행함으로써 이점을 얻을 수 있을지는 스스로 판단해야 합니다.


주의:__main__ 모듈은 보통 에서 나오지 않습니다.__main__.py파일은 가능하지만, 보통은 그렇지 않아요그런 스크립트를 실행할 때python my_program.py, 스크립트는 router로 실행됩니다.__main__모듈 대신my_program모듈.이 문제는 다음과 같이 동작하는 모듈에서도 발생합니다.python -m my_module, 또는 다른 여러 가지 방법으로.

이름을 보셨다면__main__에러 메시지에서, 그것이 반드시, 당신이 이 에러 메시지를 찾는다는 것을 의미하지는 않는다.__main__.py파일.

이 뭐죠?__main__.py신청하시겠습니까?

Python 모듈을 만들 때 모듈에서 몇 가지 기능을 실행시키는 것이 일반적입니다(일반적으로 Python 모듈은main프로그램 진입점으로 실행될 때 기능).이것은 보통 대부분의 Python 파일 하단에 다음과 같은 일반적인 관용구를 배치하여 이루어집니다.

if __name__ == '__main__':
    # execute only if run as the entry point into the program
    main()

Python 패키지에 대해 동일한 의미론을 얻을 수 있습니다.__main__.py다음과 같은 구조를 가질 수 있습니다.

.
└── demo
    ├── __init__.py
    └── __main__.py

이를 확인하려면 아래를 Python 3 쉘에 붙여넣습니다.

from pathlib import Path

demo = Path.cwd() / 'demo'
demo.mkdir()

(demo / '__init__.py').write_text("""
print('demo/__init__.py executed')

def main():
    print('main() executed')
""")

(demo / '__main__.py').write_text("""
print('demo/__main__.py executed')

from demo import main

main()
""")

데모를 패키지로 취급하여 실제로 Import할 수 있습니다.이것에 의해, Demo의 최상위 코드가 실행됩니다.__init__.py(단,main기능):

>>> import demo
demo/__init__.py executed

패키지를 프로그램의 엔트리 포인트로 사용하는 경우,__main__.py를 Import 합니다.__init__.py첫 번째:

$ python -m demo
demo/__init__.py executed
demo/__main__.py executed
main() executed

이것은, 메뉴얼로부터 도출할 수 있습니다.문서에는 다음과 같이 기재되어 있습니다.

__main__- 최상위 스크립트 환경

'__main__'는 최상위 코드가 실행되는 스코프 이름입니다.모듈의__name__와 동등하게 설정되어 있다.'__main__'표준 입력, 스크립트 또는 대화형 프롬프트에서 읽을 때 사용합니다.

모듈은 자신의 모듈을 체크함으로써 메인 스코프에서 동작하고 있는지 여부를 검출할 수 있습니다.__name__이를 통해 모듈 내의 코드가 스크립트로 실행되거나 모듈 내의 코드를 조건부로 실행하기 위한 일반적인 관용구를 사용할 수 있습니다.python -m그러나 가져올 때는 그렇지 않습니다.

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

패키지의 경우 동일한 효과를 얻을 수 있습니다.__main__.py과 함께 때 그 이 실행됩니다.-m.

압축된

도 있습니다.__main__.py를 단일 같이 할 수 있습니다, 포인트로 수 .

from pathlib import Path

demo = Path.cwd() / 'demo2'
demo.mkdir()

(demo / '__init__.py').write_text("""
print('demo2/__init__.py executed')

def main():
    print('main() executed')
""")

(demo / '__main__.py').write_text("""
print('demo2/__main__.py executed')

from __init__ import main

main()
""")

변경에 해 주세요.「 」 「 」 「 」 「 」 「 」 「 」 「 」를 Import 하고 .입합니니다다main부터__init__대신demo2- 이 zip 디렉토리는 패키지로 취급되지 않고 스크립트 디렉토리로 취급됩니다.따라서, 이 기능은, 이 기능을 탑재하고 있지 않은 상태로 되어 있을 필요가 있습니다.-m플래그를 설정합니다.

특히 질문과 관련이 있습니다.zipapp압축된 디렉토리가 실행되도록 합니다.__main__.py디폴트 - 먼저 실행됩니다.__init__.py:

$ python -m zipapp demo2 -o demo2zip
$ python demo2zip
demo2/__main__.py executed
demo2/__init__.py executed
main() executed

이 압축된 디렉토리는 패키지가 아니므로 가져올 수도 없습니다.

작성하다__main__.pyyourpackage다음 방법으로 실행할 수 있습니다.

$ python -m yourpackage

여기에서는, 「패키지」디렉토리(명시적 유무에 관계없이)가 지정되어 있는 것을 나타내고 있습니다.__init__.py파일)이 포함되어 있습니다.__main__.py이 디렉토리의 실행은, 이 디렉토리의 실행과 다른 점은 없습니다.-m전환 여부를 지정합니다.

가장 큰 차이점은 이 모든 것이-msys.path 라고 하는 디렉토리가 최초로 패스에 추가되고 나서, 파일은 패키지 의미 없이 정상적으로 실행됩니다.

반면,-m스위치, 패키지 의미론(상대 Import 포함)이 적용되며 패키지 디렉토리 자체는 시스템 경로에 추가되지 않습니다.

이는 상대적인 Import가 기능하는지 여부에 관한 매우 중요한 차이이며, 시스템 모듈의 의도하지 않은 섀도우잉이 발생했을 무엇을 Import할지를 지시하는 점에서 더욱 중요합니다.


예:

라고 하는 디렉토리를 생각해 주세요.PkgTest다음과 같은 구조로

:~/PkgTest$ tree
.
├── pkgname
│   ├── __main__.py
│   ├── secondtest.py
│   └── testmodule.py
└── testmodule.py

어디서__main__.pyfile의 내용은 다음과 같습니다.

:~/PkgTest$ cat pkgname/__main__.py
import os
print( "Hello from pkgname.__main__.py. I am the file", os.path.abspath( __file__ ) )
print( "I am being accessed from", os.path.abspath( os.curdir ) )
from  testmodule import main as firstmain;     firstmain()
from .secondtest import main as secondmain;    secondmain()

(다른 파일도 마찬가지로 정의되어 있고, 출력도 비슷합니다).

이 명령어를 사용하지 않고 실행하면-m스위치, 이게 네가 얻을 수 있는 거야상대적인 Import는 실패하지만 더 중요한 것은 잘못된 테스트모듈이 선택되었다는 것입니다(즉, 작업 디렉토리와 관련됨).

:~/PkgTest$ python3 pkgname
Hello from pkgname.__main__.py. I am the file ~/PkgTest/pkgname/__main__.py
I am being accessed from ~/PkgTest
Hello from testmodule.py. I am the file ~/PkgTest/pkgname/testmodule.py
I am being accessed from ~/PkgTest
Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "pkgname/__main__.py", line 10, in <module>
    from .secondtest import main as secondmain
ImportError: attempted relative import with no known parent package

한편, -m 스위치에서는, (바람직하게) 기대한 대로의 결과를 얻을 수 있습니다.

:~/PkgTest$ python3 -m pkgname
Hello from pkgname.__main__.py. I am the file ~/PkgTest/pkgname/__main__.py
I am being accessed from ~/PkgTest
Hello from testmodule.py. I am the file ~/PkgTest/testmodule.py
I am being accessed from ~/PkgTest
Hello from secondtest.py. I am the file ~/PkgTest/pkgname/secondtest.py
I am being accessed from ~/PkgTest


참고: 제 솔직한 의견으로는,-m피해야 합니다.사실, 저는 더 나아가서 제가 이 모든 것을 만들겠다고 말하고 싶습니다.executable packages통과하지 않으면 실패할 수 있습니다.-m전환합니다.

즉, 다른 모든 Import가 시스템 모듈을 나타낸다고 가정할 때, "in-package" 모듈에서 "relative imports"를 통해 명시적으로만 Import합니다.다른 사용자가 패키지를 실행하려고 할 때-m스위치에서는 잘못된 모듈을 사일런트하게 실행하는 대신 상대적인 Import 스테이트먼트가 에러를 발생시킵니다.

__main__.pyzip 파일의 python 프로그램에 사용됩니다.__main__.pyzip 파일이 실행 중일 때 파일이 실행됩니다.예를 들어 zip 파일이 다음과 같은 경우:

test.zip
     __main__.py

및 의 내용__main__.py이었다

import sys
print "hello %s" % sys.argv[1]

우리가 도망친다면python test.zip world우리는 얻을 수 있을 것이다hello world나가.

그래서...__main__.pyzip 파일에서 python이 호출되면 file이 실행됩니다.

스크립트가 단일 python 파일이 아닌 디렉토리 또는 ZIP 파일인 경우__main__.py"script"가 python 인터프리터에 인수로 전달될 때 실행됩니다.

언급URL : https://stackoverflow.com/questions/4042905/what-is-main-py

반응형