2012-09-21 3 views
1

제목이 어리석은 것 같지만 정확하게 표현하는 법을 모르겠습니다. 죄송합니다.Python : eval의 전역 변수에 액세스하는 방법

(보안을 위해 RestrictedPython을 통해) 일부 사용자 코드를 평가해야하는 프로그램이 있으며 eval의 전역에 함수를 추가하여 eval, 예를 들어 몇 가지 디버그 정보를 인쇄 할 수 있습니다.) :

class UserException(Exception): 
    pass 


def err(msg): 
    # ? how to get the globals variable in eval ? 
    A = globals().get('A', 'A not found') 
    return UserException("%s and A's value is %r" % (msg, A)) 

g = { 
    'err': err, 
    'A': None, 
    '__builtins__': {}, 
} 

print eval('A or err("A not true")', g) 

이이 resut 줄 것이다 :

A not true and A's value is 'A not found' 

사용 '전역을()'여기 insde '잘못한다'는 잘못된 물론이다. 그러나 '오류'내부의 'g'값을 어떻게 얻을 수 있습니까?

답변

1

함수 내부에서 globals()을 참조하면 함수가 정의되었을 때 범위에 있었던 전역 변수가 항상 제공됩니다. 여기서 볼 수있는 것은 한 모듈에서 다른 모듈로 함수를 가져올 때와 다르지 않습니다. 가져온 함수는 여전히 정의 된 모듈의 전역을 참조합니다.

gglobals()으로 사용하는 가장 간단한 방법은 g을 전역으로 사용하여 정의를 실행하는 것입니다. 함수에 대한 전역 변수를 변경했다면 함수를 사용하는 다른 전역 변수도 포함시켜야합니다. 이 경우 UserException.

또는 err()을 호출자의 스택 프레임을 검사하고 호출자의 전역을 사용할 수 있습니다. 그건 지저분하지만, 디버그 정보가 있다면 당신에게 받아 들여질 수 있습니다.

>>> def err(msg): 
    # ? how to get the globals variable in eval ? 
    A = sys._getframe(1).f_globals.get('A', 'A not found') 
    return UserException("%s and A's value is %r" % (msg, A)) 

>>> import sys 
>>> g = { 
    'err': err, 
    'A': None, 
    '__builtins__': {}, 
} 
>>> print eval('A or err("A not true")', g, g) 
A not true and A's value is None 
>>> 
+0

예, 그게 내가 찾고있는 것입니다. inspect 모듈을 사용하여 동일한 효과를 얻습니다. – jayven

1

당신은 기본 인수로 그것을 g을 전달할 수 : A not true and A's value is None :

def err(msg, g=g): 
    A = g['A'] 
    return UserException("%s and A's value is %r" % (msg, A)) 

이 결과를 제공 할 것입니다.

관련 문제