根据评论,您的目标是取回您不直接调用的函数的返回状态,并且您希望避免使用全局变量。在 C 语言中,您别无选择,只能使用引用,但在 python 中,您比局部变量和(C 风格)全局变量具有更大的灵活性:您可以使用“闭包”让回调直接分配给局部变量。
在 Python 3 中
如果您使用 python 3,您可以使用nonlocal
关键字直接执行此操作。最简单的情况是当您在现场定义回调时:
myfunction():
x = None
def callback():
nonlocal x # Python 3 only
x = 5
gtk.somefunction(callback) # Executes callback()
print "My callback returned", x
但是您的回调可能是在其他地方定义的,或者是从许多不同的地方调用的?没问题,只需在现场定义一个捕获真正回调的返回值的包装器:
def real_callback():
return 11
def myfunction():
x = 0
def wrapper():
nonlocal x # Python 3 only
x = real_callback()
gtk.somefunction(wrapper)
print "my callback returned", x
这可以通过wrapper
变成装饰器来掩盖,但那是另一回事。
Python 2 解决方案
在 python 2 中没有nonlocal
语句,并且隐式闭包是只读的:如果你在没有nonlocal
语句的情况下尝试上面的方法,你会得到一个错误。如果您声明它global
,您可以分配给一个变量,仅此而已。所以,一些诡计是必要的:
首先,该函数locals()
返回一个包含本地上下文所有变量的字典。locals()['x']
是局部变量x
。但locals()
通常是只读的。幸运的是,有一个很好的(或糟糕的)解决方法:出于自身原因,exec
禁用呈现locals()
只读的优化......而且,事实证明,它在调用函数的生命周期内保持禁用状态!(在 Python 2.6.6,YMMV 上测试。如果它不起作用,请尝试exec "a = 0"
)。所以,你可以这样做:
def wrapper(callback, context, varname):
def _callback():
context[varname] = callback()
return _callback
def mycode():
exec ""
some_library_function(wrapper(real_callback, locals(), 'z'))
print "The callback returned", z
这比仅使用可变容器作为返回值更可取吗?我猜这是口味问题。但是你可以多次使用同一个包装器,所以从某种意义上说它比 python 3 解决方案更干净......如果你忽略了魔法exec
。