2016-08-18 3 views
1

하위 함수가있는 함수가 있는데 하위 함수 내부의 변수를 초기화하고 싶습니다. 간단하게,변수 파일 이름의 함수 (하위 함수)에 변수 설정

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     var1 = 0 
     var2 = 1 
     var3 = 2 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

출력 : bar 0 1 2

는 그러나, 나는 여러 다른 파일의 변수 꽤 많은 수를 가지고 있고이 하위 메뉴가 호출 될 때 단순히 하위 메뉴로 가져올하고 싶습니다.

var1=0 
var2=1 
var3=2 

가 그럼 난이 때 파이썬 2.7이 그것을 좋아하지 않기 때문에 오류가 발생하는 것입니다

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     from file import * 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

으로 코드를 변경 : 나는 다음과 같은 내용의 파일 bar.py 있다고 가정 서브 함수 내에서 import을 사용하십시오. 그래서, 대신, 우리는 직접 __import__ 기능을 사용할 수 있습니다

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     __import__(file) 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

가져 오기 방법은 여기에 작동을하지만, 변수는 이제까지 실제로 내가 인쇄에 갈 때 오류의 결과로, 하위 기능의 변수 목록에하지 않는다 그들 밖으로. 자, 코드를

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     f = __import__(file) 
     print file, f.var1, f.var2, f.var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

으로 변경할 수 있다는 것을 알고 있습니다. 그러면 peachy가 작동합니다. 그것은 내가 찾고있는 솔루션이 아닙니다. 나머지 코드를 수정하지 않고 이러한 함수를 가져올 수 있기를 원합니다. 이 문제에 대한 더 나은 해결책이 있습니까?

+0

왜 파일 및 개체를 만든 다음 인스턴스화 할 수 없습니까? 그럼 그냥 file.property (file.var1)를 할 수도 있고, 계산을하고 싶다면 getter 함수를 사용할 수도 있습니다. – kyle

+0

파이썬 임포트 시스템에 대해 혼란 스러울 것 같습니다. "Python 2.7은 하위 함수 내에서 가져 오기를 사용하면 좋아하지 않습니다." 아니...어떤 버전의 Python에서는 범위에 관계없이 import 문에서 변수를 사용할 수 없습니다. "여기에있는 가져 오기 방법이 작동하지만 변수가 [로컬 범위에 추가되지 않습니다]." 음, 아니, 그것은 어떤 상황에서도 '수입 x'가 어떻게 작동하는지 아닙니다. 나는 너의 세 번째 요점을 정말로 이해하지 못한다. –

+2

또한, 그저 설정이라면 어쩌면 "실행"하려고 시도하는 대신 구문 분석해야합니다. 예를 들어, [configparser] (https://docs.python.org/3/library/configparser.html)를 사용하여 – spectras

답변

0

유지 관리의 관점에서 모듈을 가져온 다음 모듈의 변수를 참조하는 것이 가장 좋습니다. 변수가 어디서 왔는지 쉽게 알 수 있습니다.

from module import *은 변수가 어디서 왔는지 추적하기 어렵 기 때문에, 특히 여러 모듈에 동일한 이름의 변수가있는 경우에 눈살을 찌푸립니다. from module import *은 파이썬에서 로컬 변수가 작동하는 방식 때문에 함수 내에서 불가능합니다. 지역 변수는 스택에 저장되며, 파이썬이 얼마나 많은 변수가 있는지 알지 못한다면 스택에 공간을 적절하게 할당 할 수 없습니다.

하지만 그건 당신이 원하는 것을 할 수 있다고 말했습니다. 그러나 그렇게해서는 안됩니다. 이것의 배경은 전역 변수로 참조 된 변수를 그대로두고 함수가 시작될 때 전역 변수를 업데이트하는 것입니다. 예.

from importlib import import_module 

file_ = "foo" 
def outer(): 
    def inner(): 
     m = import_module(file_) # import module whose name is the contents of file_ 
     globals().update(m.__dict__) # add module's globals to our own 
     print(file_, var0, var1, var2) 
    file_ = "bar" 
    inner() 
outer() 

이 전역의 동일한 세트를 공유하는 각각의 내부 기능으로서 끔찍한 생각 가능한 동일한 이름의 변수를 겹쳐있다. inner 함수가 동시에 실행되거나 outer을 정의한 모듈에 필요한 변수를 덮어 쓰는 경우 문제가 발생합니다. 각 inner 함수를 고유 한 전역 집합을 사용하도록 수정하여이 문제를 극복하는 것이 가능하지만, 이는 끔찍한 해킹이며이를 주로 어떻게 포함 할 수 있는지 보여주기 위해 포함됩니다.

from importlib import import_module 
from types import FunctionType 

file_ = "foo" 
def outer(): 
    def inner(): 
     m = import_module(file_) 
     globals().update(m.__dict__) 
     print(file_, var0, var1, var2) 
    # redefine inner with new globals 
    inner = FunctionType(inner.__code__, 
     dict(import_module=import_module, __builtins__=__builtins__), # new globals 
     inner.__name__, inner.__defaults__, inner.__closure__ 
    ) 
    file_ = "bar" 
    inner() 
outer()