Как получить gobject.idle_add () для передачи параметра по ссылке? - PullRequest
2 голосов
/ 01 мая 2011

В моем приложении PyGTK есть две темы:

  • основной поток, который запускает цикл GTK и выполняет всю работу с графическим интерфейсом
  • другой поток, который обрабатывает сетевые запросы и т. Д.

Мне нужно, чтобы второй поток получил некоторую информацию из первого потока, поэтому я звоню:

* * 1010

В основной теме у меня есть:

def function_in_main_thread( variable ):
    variable = 1

Проблема в том, что переменная во втором потоке никогда не устанавливается. Это значение остается на None. Так как же я могу заставить основной поток на самом деле изменить переменную в другом потоке?

Примечание: У меня есть некоторый код синхронизации потоков в сценарии на случай, если кто-нибудь захочет изменить переменные в других потоках. Я пропустил это из этого примера, потому что я чувствовал, что это действительно не относится к реальной проблеме.

1 Ответ

3 голосов
/ 01 мая 2011

В 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]

Конечно, список может быть в равной степени просто пустым объектом с элементом value.

Короче говоря, если вы хотите сделать что-то похожее на вызов по ссылке, избегайте оператора присваивания .Вместо этого используйте какой-то метод объекта.


Существует аккуратное и удивительно краткое руководство по пространствам имен Python от Shrutarshi Basu, на случай, если вы захотите копнуть глубже.Чтобы понять, что делает оператор присваивания, посмотрите wp: Name Binding .Это также объясняет, почему оператор присваивания не может быть перегружен в Python.


Кроме того, как указал вы , вам нужно позвонить gobject.threads_init()

...