我想动态声明一个函数,我想包装任何对全局变量的访问,或者替代地定义哪些变量是免费的,并包装任何访问自由变量。
我在玩这样的代码:
class D:
def __init__(self):
self.d = {}
def __getitem__(self, k):
print "D get", k
return self.d[k]
def __setitem__(self, k, v):
print "D set", k, v
self.d[k] = v
def __getattr__(self, k):
print "D attr", k
raise AttributeError
globalsDict = D()
src = "def foo(): print x"
compiled = compile(src, "<foo>", "exec")
exec compiled in {}, globalsDict
f = globalsDict["foo"]
print(f)
f()
这将产生输出:
D set foo <function foo at 0x10f47b758>
D get foo
<function foo at 0x10f47b758>
Traceback (most recent call last):
File "test_eval.py", line 40, in <module>
f()
File "<foo>", line 1, in foo
NameError: global name 'x' is not defined
我想要的是用类似dict的包装器来获取对
x
的访问。我该怎么做?我不想预先定义所有全局变量(在本例中为
D
),因为我希望能够惰性地加载它们。 最佳答案
你要找的是对象代理。
下面是支持调用前和调用后挂钩的对象代理的配方:
http://code.activestate.com/recipes/366254-generic-proxy-object-with-beforeafter-method-hooks/
创建一个不实际加载对象的子类,直到第一次调用_pre
钩子。任何访问对象的操作都将导致加载真正的对象,并且所有调用似乎都由真正的对象直接处理。