如果我EVAL的东西在Python:是否有可能从上层栈帧获取locals()和globals()?
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
这种实现方式如下:
- 如果我使用一个表达式对象(其实我开发了这样的对象),那么我评价这种表达使用当前对象(毕竟这个函数是一个方法)。这部分不需要帮助,它得到了充分的发展。
- 如果我使用可调用对象,则执行可调用对象(例如lambda表达式)。
- 如果我使用一个字符串,那将是一个python表达式,我希望使用调用时间
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()
?
在这个设计中,请考虑“如果每个人都想做同样的事情你会怎样是?”问题。也就是说,假设你得到你想要的,然后我想编写另一个调用你的'__eval'的便利函数。我该如何告诉它,“不,不是,这个堆栈框架继续上升到另一个层次”? – 2014-12-06 16:30:46
如果您敢于调用'scope ['$ eval'](“a + b”)'这是我在这里不会解释的原因 - 调用__eval的实际方法(是的,它是一种AngularJS端口, Python,但部分),那么你会使用调用时间的词法范围(这样的词法范围有一个额外的处理,让'self'指向当前的$ scope对象)。它现在工作:)。 – 2014-12-08 13:49:12
但是,尽管我问了这个奇怪的用例,但它不是最常用的用例。 $ eval将总是在$ watch调用中调用(毕竟,它是 - 部分是AngularJS $ rootScope端口)。 – 2014-12-08 13:51:29