是否有可能从上层堆栈框架中获取locals()和globals()?

时间:2014-12-06 16:23:34

标签: python

如果我在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

此实现解释如下:

  • 如果我使用表达式对象(我实际开发了这样的对象),那么我使用当前对象来评估这样的表达式(毕竟,这个函数是一个方法)。这部分无需帮助,它已经完全开发出来。
  • 如果我使用callable,我执行callable(例如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这样的evallocals(),而不会让用户明确地传递它,并在globals()中使用这些值。

问题:是否可以从上部堆栈框架中获取{{1}}和{{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