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