1

我本质上需要的是一个可变整数,它可以完成下面的等效操作,而不必求助于使用单元素列表。

下面是一个人为的代码示例,它代表了我的实际用例[1]的本质

>>> a = [5]  
>>> b = [77]  
>>> def swap(num1, num2):  
...     temp = num1[0]  
...     num1[0] = num2[0]  
...     num2[0] = temp  
>>> swap(a, b)  
>>> a  
[77]  
>>> b  
[5]  

[1]我的实际用例更接近这个 -> 在 Tkinter 中使用按钮调用函数后返回一个值
我需要从与 Tkinter 小部件关联的回调函数返回一个值,并且我想避免使用全局变量。

4

3 回答 3

5

恐怕你必须使用一个类。Python 是一种高级语言,不支持 C(和 C++)中存在的指针恶作剧,因此您需要使用一个保存整数值的对象,然后您可以对其进行修改。

于 2012-12-08T19:57:01.107 回答
2

根据评论,您的目标是取回您不直接调用的函数的返回状态,并且您希望避免使用全局变量。在 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

于 2012-12-08T22:39:58.897 回答
0

在回调的上下文中(请参阅对 Santiclaus 答案的评论),您可能希望将类似Queue的内容传递给回调函数,并让回调通过队列发布其结果。然后你的主线程可以在这个队列上等待它的结果。

于 2012-12-08T22:40:46.160 回答