当我为 传递真正的 dict 时locals
,exec()
会做正确的事情并回退到 globals 字典以查找缺少的名称。但是,如果我将 LazyMap(类 dict 对象)作为局部变量传递,则对全局变量的访问会从提供给 LazyMap 的 lambda 内部引发 AttributeError。
#!/usr/bin/env python3
class LazyMap:
def __init__(self, keys, getter):
self._keys = keys
self._getter = getter
def keys(self):
return self._keys
def __getitem__(self, k):
return self._getter(k)
class TestObj:
def __init__(self):
self.field = 'foo'
obj = TestObj()
# this prints 'foo'
locs = dict((name, getattr(obj, name)) for name in dir(obj))
exec('print(field)', globals(), locs)
# this raises AttributeError
locs = LazyMap(dir(obj), lambda k,s=obj: getattr(s, k))
exec('print(field)', globals(), locs)
为什么 LazyMap 会引发异常,但普通 dict 不会引发异常?如果从 exec 访问,我如何创建一个只会获取/计算值的本地映射?