开发者

How to get gobject.idle_add() to pass a parameter by reference?

I have two threads in my Py开发者_StackOverflow社区GTK app:

  • the main thread which runs the GTK loop and does all the GUI stuff
  • another thread which handles network requests, etc.

I need to have the second thread get some information from the first thread, so I call:

variable = None
gobject.idle_add( function_in_main_thread, variable )

In the main thread I have:

def function_in_main_thread( variable ):
    variable = 1

The problem is that the variable in the second thread never gets set. It's value remains at None. So how can I get the main thread to actually modify the variable in the other thread?

Note: I have some thread synchronization code in the script in case anyone is concerned about modifying variables in other threads. I omitted it from this example because I felt it really didn't apply to the real issue.


In Python, assignment always creates the name in the current scope. The name you pass is indeed a reference to the variable you've created, but the assignment operator will try to find it in the current scope and, if it's not there, create it.

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

You can instead pass a reference to some kind of instance, a type or maybe even a list, and then use some method of that instance.

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

The list could of course equally be just an empty object with a "value" member.

In short, if you want to do something akin to call by reference, avoid the assignment operator. Use some kind of method of the object instead.


There's a neat, and surprisingly terse guide to Python Namespaces by Shrutarshi Basu, in case you want to dig deeper. In order to understand what the assignment operator is doing, check out wp: Name Binding. It also explains why the assignment operator can't be overloaded in Python.


Also, as you pointed out, you need to call gobject.threads_init()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜