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

时间:2011-05-01 02:00:48

标签: python multithreading variables pygtk

我的PyGTK应用程序中有两个主题:

  • 运行GTK循环并完成所有GUI内容的主线程
  • 处理网络请求等的另一个线程

我需要让第二个线程从第一个线程获取一些信息,所以我打电话给:

variable = None
gobject.idle_add( function_in_main_thread, variable )

在主线程中我有:

def function_in_main_thread( variable ):
    variable = 1

问题是第二个线程中的变量永远不会被设置。它的值保持在None。那么如何让主线程实际修改另一个线程中的变量?

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

1 个答案:

答案 0 :(得分: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有一个整洁的,令人惊讶的简洁guide to Python Namespaces,以防你想深入挖掘。为了理解赋值运算符的作用,请查看wp: Name Binding。它还解释了为什么赋值运算符不能在Python中重载。


另外,正如指出的那样,你需要拨打gobject.threads_init()