如何让gobject.idle_add()按引用传递参数?

2 投票
1 回答
1324 浏览
提问于 2025-04-16 16:44

我在我的PyGTK应用程序中有两个线程:

  • 一个是主线程,它负责运行GTK循环和处理所有的界面相关工作
  • 另一个线程则负责处理网络请求等事情

我需要让第二个线程从第一个线程获取一些信息,所以我调用了:

variable = None
gobject.idle_add( function_in_main_thread, variable )

在主线程中,我有:

def function_in_main_thread( variable ):
    variable = 1

问题是,第二个线程中的变量从来没有被设置。它的值一直是None。那么我该如何让主线程真正地修改另一个线程中的变量呢?

注意:我在脚本中有一些线程同步的代码,以防有人担心在其他线程中修改变量。我在这个例子中省略了它,因为我觉得这并不适用于实际问题。

1 个回答

3

在Python中,赋值操作总是会在当前的作用域中创建一个名字。你传入的名字其实是你创建的变量的一个引用,但赋值符号会先在当前作用域中查找这个名字,如果找不到,就会新建一个。

>>> def assign_to(name, value):
...     name = value
...
>>> name = "nothing"
>>> assign_to(name, 5)
>>> name
'nothing'

你也可以传入某种实例的引用,比如一个类型或者甚至是一个列表,然后使用这个实例的一些方法。

>>> def append_to_list(my_list, value):
...     my_list.append(value)
... 
>>> my_list = []
>>> append_to_list(my_list, 5)
>>> my_list
[5]

这个列表当然也可以只是一个空对象,里面有一个“值”的成员。

简单来说,如果你想做类似于按引用传递的操作,最好避免使用赋值符号。可以用对象的一些方法来代替。


如果你想深入了解,还有一篇由Shrutarshi Basu写的关于Python命名空间的简洁而有趣的指南。要理解赋值符号的作用,可以看看维基百科:名字绑定。它也解释了为什么在Python中赋值符号不能被重载。


另外,正如提到的,你需要调用gobject.threads_init()

撰写回答