如果我在Python中评估一些东西:
eval("a + b")
这将使用当前范围(本地和全局)来评估表达式。
我正在开发的内容要求“稍后”评估表达式。这个词意味着我想保留当前的范围(即locals()
和globals()
)。但是我希望透明地传递这些值......或者从上层栈帧中获取它们。考虑这个实现(实际上,这个实现):
def __eval(self, expr):
if isinstance(expr, (list, tuple, set, frozenset, dict, Expression)):
return Expression.eval(expr, self)
elif callable(expr):
try:
return expr(self)
except (AttributeError, IndexError, KeyError, TypeError):
return UNDEFINED
else:
try:
return eval(expr, {}, {'self': self})
except (AttributeError, IndexError, KeyError, TypeError):
return UNDEFINED
此实现解释如下:
locals()
和globals()
执行此类评估。我知道我可以明确地致电:
o._O__eval("self.a + self.b", globals(), locals())
#THIS WOULD REQUIRE to alter the method to allow two additional dict parameters
#NO, I will not call this function directly, but lets follow the example
但是我希望得到globals()
和locals
这样的eval
和locals()
,而不会让用户明确地传递它,并在globals()
中使用这些值。
问题:是否可以从上部堆栈框架中获取{{1}}和{{1}}?
答案 0 :(得分:5)
你应该考虑传入 globals()
和locals()
:
def __eval(self, expr, eval_globals=None, eval_locals=None):
if eval_globals is None:
eval_globals = globals()
if eval_locals is None:
eval_locals = eval_globals()
如果这不适合您,您可以使用sys._getframe()
function访问父框架,而locals和globals是该框架的属性:
def __eval(self, expr, eval_globals=None, eval_locals=None):
call_frame = sys._getframe(1)
eval_globals, eval_locals = call_frame.f_globals, call_frame.f_locals