[PYTHON] 모듈 가져 오기 : __main__ 대 모듈 가져 오기
PYTHON모듈 가져 오기 : __main__ 대 모듈 가져 오기
머리말을하기 위해이 코드를 가져 오는 방법 (가져온 후에 모듈 변수를 변경하는 방법을 기반으로)을 얻는 방법을 찾은 것 같지만 다음 질문이 실제로 발생하는 이유는 무엇인가에 대해 이해할 수 있습니다.
3 개의 파일이 있습니다. 첫 번째는 mod1.py입니다.
# mod1.py
import mod2
var1A = None
def func1A():
global var1
var1 = 'A'
mod2.func2()
def func1B():
global var1
print var1
if __name__ == '__main__':
func1A()
다음으로 mod2.py가 있습니다.
# mod2.py
import mod1
def func2():
mod1.func1B()
마지막으로 driver.py :
# driver.py
import mod1
if __name__ == '__main__':
mod1.func1A()
python mod1.py 명령을 실행하면 출력은 None입니다. 위에서 언급 한 링크를 기반으로, mod2.py에서 가져 오는 mod1.py와 __main__으로 가져 오는 mod1.py 사이에는 약간의 차이가있는 것으로 보입니다. 따라서 driver.py를 만들었습니다. python driver.py 명령을 실행하면 예상되는 결과를 얻을 수 있습니다. A. 일종의 차이점을 볼 수는 있지만 실제로 메커니즘이나 그 이유는 알 수 없습니다. 어떻게 그리고 왜 이런 일이 발생합니까? 똑같은 모듈이 두 번 존재한다는 것은 반 직관적 인 것처럼 보인다. 파이썬 mod1.py를 실행하면 mod2.py에서 가져온 버전의 변수 대신 mod1.py의 __main__ 버전의 변수에 액세스 할 수 있습니까?
해결법
-
==============================
1.__name__ 변수는 파일이 인터프리터에 스크립트로로드 된 경우를 제외하고 항상 모듈의 이름을 포함합니다. 그 변수는 대신 '__main__'문자열로 설정됩니다.
__name__ 변수는 파일이 인터프리터에 스크립트로로드 된 경우를 제외하고 항상 모듈의 이름을 포함합니다. 그 변수는 대신 '__main__'문자열로 설정됩니다.
결국 스크립트는 전체 프로그램의 주 파일로 실행되고, 그 밖의 모든 모듈은 해당 주 파일에 의해 직접 또는 간접적으로 가져옵니다. __name__ 변수를 테스트하면 파일을 모듈로 가져 왔는지 또는 직접 실행했는지 감지 할 수 있습니다.
내부적으로 모듈에는 sys.modules의 각 모듈에 대한 메타 데이터의 일부로 저장된 네임 스페이스 사전이 제공됩니다. 실행 된 스크립트 인 주 파일은 '__main__'과 동일한 구조로 저장됩니다.
하지만 파일을 모듈로 가져올 때, 파이썬은 먼저 sys.modules를보고 그 모듈이 이미 이전에 가져 왔는지 확인합니다. 따라서 import mod1은 sys1.modules에서 mod1 모듈을 먼저 찾습니다. mod1이 아직 없으면 네임 스페이스가있는 새로운 모듈 구조가 생성됩니다.
따라서 mod1.py를 주 파일로 실행하고 나중에 python 모듈로 가져 오면 sys.modules에 두 개의 네임 스페이스 항목이 생깁니다. 하나는 '__main__', 나중에는 'mod1'입니다. 이 두 네임 스페이스는 완전히 별개입니다. 전역 var1은 sys.modules [ '__ main__']에 저장되지만 func1B는 sys.modules [ 'mod1']에서 var1을 찾고 있습니다 (None 인 경우).
그러나 python driver.py를 사용하면 driver.py는 프로그램의 '__main__'주 파일이되고 mod1은 sys.modules [ 'mod1'] 구조로 한 번만 가져옵니다. 이번에는 func1A가 var1을 sys.modules [ 'mod1'] 구조체에 저장하고 func1B가 찾을 것입니다.
-
==============================
2.선택적으로 주 스크립트로 모듈을 사용하기위한 실질적인 솔루션 - 일관된 교차 - 가져 오기 지원 :
선택적으로 주 스크립트로 모듈을 사용하기위한 실질적인 솔루션 - 일관된 교차 - 가져 오기 지원 :
예 : 파이썬 pdb 모듈에서, __main__ (결국)으로 실행할 때 자신을 임포트하여 스크립트로 실행하는 방법 :
#! /usr/bin/env python """A Python debugger.""" # (See pdb.doc for documentation.) import sys import linecache ... # When invoked as main program, invoke the debugger on a script if __name__ == '__main__': import pdb pdb.main()
__main__ 시작을 다음과 같이 스크립트 시작 부분으로 재구성하는 것이 좋습니다.
#! /usr/bin/env python """A Python debugger.""" # When invoked as main program, invoke the debugger on a script import sys if __name__ == '__main__': ##assert os.path.splitext(os.path.basename(__file__))[0] == 'pdb' import pdb pdb.main() sys.exit(0) import linecache ...
이렇게하면 모듈 본체가 두 번 실행되지 않습니다. 이는 "비용이 많이 드는", 바람직하지 않으며 때로는 중요합니다.
드문 경우에는 실제 모듈 별명 (mod1)으로 직접 실제 스크립트 모듈 __main__을 노출하는 것이 바람직합니다.
# mod1.py import mod2 ... if __name__ == '__main__': # use main script directly as cross-importable module _mod = sys.modules['mod1'] = sys.modules[__name__] ##_modname = os.path.splitext(os.path.basename(os.path.realpath(__file__)))[0] ##_mod = sys.modules[_modname] = sys.modules[__name__] func1A()
알려진 단점 :
from https://stackoverflow.com/questions/13181559/importing-modules-main-vs-import-as-module by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Python FTP는 날짜별로 최신 파일을 가져옵니다. (0) | 2018.10.15 |
---|---|
[PYTHON] 사용자 입력에서 동적으로 명명 된 변수 만들기 [duplicate] (0) | 2018.10.15 |
[PYTHON] 쓰레드를 죽일 방법이 있습니까? (0) | 2018.10.15 |
[PYTHON] 동일한 이름을 가진 로컬 모듈이있을 때 Python에서 표준 라이브러리 모듈에 액세스하는 방법? (0) | 2018.10.15 |
[PYTHON] 일련의 문자열 분해 / 스택 (0) | 2018.10.14 |