Python:如何动态设置函数闭包环境

Alb*_*ert 6 python eval compilation global-variables dynamic-execution

我想动态声明一个函数,我想包装对全局变量的任何访问,或者定义哪些变量是空闲的,并包装对自由变量的任何访问.

我正在玩这样的代码:

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()
Run Code Online (Sandbox Code Playgroud)

这会产生输出:

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
Run Code Online (Sandbox Code Playgroud)

我想要的是以某种方式捕获x与我的类似dict的包装器的访问D.我怎样才能做到这一点?

我不想预定义所有全局变量(在这种情况下x),因为我希望能够懒惰地加载它们.

agf*_*agf 2

您正在寻找的是对象代理

以下是支持调用前和调用后挂钩的对象代理的配方:

http://code.activestate.com/recipes/366254-generic-proxy-object-with-beforeafter-method-hooks/

_pre创建一个子类,直到第一次调用钩子时才实际加载对象。任何访问该对象的操作都会导致真实对象被加载,并且所有调用都将看起来是由真实对象直接处理的。