2011-08-17 6 views
3

runpy 모듈을 사용하여로드 된 파일에 정의 된 메서드를 실행하려고하면 예기치 않은 동작이 발생합니다. 메소드는 해당 메소드 외부에 정의 된 변수 (가져온 모듈 포함)를 볼 수 없습니다.뚜껑이 닫힌 상태에서 어떻게 작동합니까?

#test.py 
import runpy 
env = runpy.run_path('test', {'y':'world'}) 
env['fn']() 

~

#test 
import re 

print(re.compile(r'^hello', re.IGNORECASE).sub('', "hello world")) 
x = "hello" 
print(x) 
print(y) 

def fn(): 
    try: 
     print(re.compile(r'^hello', re.IGNORECASE).sub('', "hello world")) 
    except: 
     print("No re") 
    try: 
     print(x) 
    except: 
     print("No x") 
    try: 
     print(y) 
    except: 
     print("No y") 

test.py의 내 예상 출력은 다음과 같습니다 : FN은 재에 대한 폐쇄를 형성 할

world 
hello 
world 
world 
hello 
world 

때문에 X 여기에 내가 그 일을하고 어떻게 및 y.

그러나, 대신 내가 얻을 : 다시는 정상 폐쇄 행동해야하더라도 FN 내에서 정의되지 않은 것처럼

world 
hello 
world 
No re 
None 
None 

그것은 보인다. x와 y는 정의 된 것처럼 보이지만 None으로 설정 되었기 때문에 낯선 사람입니다.

왜 그런가요? 뚜껑이 닫힌 상태로 작동하는 이유는 무엇입니까? fn이 외부 변수를 '볼'수있는 정상적인 동작을 어떻게 얻을 수 있습니까?

답변

4

좋아, 이것은 내가 알고 있지만 완전히 이해하지 못하는 파이썬이 모듈을 다루는 방식의 호기심이다. IPython에서 작업 할 때 나는 그것을 보았습니다. 여기서는 a comment으로 설명했습니다.

파이썬이 모듈을 실행할 때 모듈의 전역 이름 인 모듈 객체를 생성합니다. 모듈이 범위를 벗어나 파괴되는 경우이 속성은 None으로 설정됩니다. 함수에서 정의 된 코드는 찾은대로이를 전역 변수로 간주합니다. 파일에 def g(): return globals()을 추가 한 다음 env["g"]()을 호출하여이를 증명할 수 있습니다.

runpy으로 끝나는 방법이 있는지 모르겠습니다. IPython은 다른 파일을 실행하기 위해 모듈 객체를 재사용하기 위해 몇 가지 복잡한 코드를 사용하여 참조를 유지하기 위해 __dict__ 사본을 캐싱합니다. 관심이 있으시면 magic_run function을보십시오.

관련 문제