2011-12-07 84 views
0

我想覆蓋全局變量,以便任何不存在的屬性名稱 返回自身(名稱字符串)。 其原因是在eval中使用它來做一些快速/ hacky的c initilizer列表解析,(當然,正因爲如此)。 我的代碼:覆蓋與__getattr__問題的eval全局變量

class EvalGlobalsDict(dict): 
    def __getattr__(self, name): 
     if hasattr(self, name): 
      return super(EvalGlobalsDict, self).__getattr__(name) 
     else: 
      return name 


eval_globals = EvalGlobalsDict(globals()) 

每當我試着EVAL它給了我一個NameError

eval("aaa",eval_globals) 

如果我嘗試直接調用

eval("globals().__getattr__("dir")",eval_globals) 
eval("globals().__getattr__("dir")",eval_globals) 

我只得到一個不存在的名字attr名稱字符串,即使是有效的attributtes。 我在做什麼錯?

+2

通過AKX給出的答案是正確的,但僅供參考'__getattr__'只被調用,如果常規屬性查找失敗,所以你不需要'if' /'else' - 只要'返回名稱'就可以做到這一點(如果它實際上是你想修改的屬性訪問)。 – agf

回答

4

由於您正在繼承字典,因此您需要覆蓋__getitem__(索引訪問器)。

class EvalGlobalsDict(dict): 
    def __getitem__(self, name): 
     return self.get(name, name) 

foo = 1337 
eval_globals = EvalGlobalsDict(globals()) 
print repr(eval("aaa", eval_globals)) 
print repr(eval("foo", eval_globals)) 

打印

> 'aaa' 
> 1337