В функции:
a += 1
будет интерпретироваться компилятором как assign to a => Create local variable a
, что вам не нужно. Вероятно, произойдет сбой с a not initialized
ошибкой, поскольку (локальный) a действительно не был инициализирован:
>>> a = 1
>>> def f():
... a += 1
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment
Вы можете получить то, что хотите, с global
ключевым словом (очень неодобрительно и по уважительным причинам) , например:
>>> def f():
... global a
... a += 1
...
>>> a
1
>>> f()
>>> a
2
В целом, однако, вам следует избегать использования глобальных переменных, которые очень быстро выходят из-под контроля. И это особенно верно для многопоточных программ, где у вас нет механизма синхронизации, чтобы вы thread1
знали, когда a
он был изменен. Вкратце: потоки сложны , и вы не можете ожидать интуитивного понимания порядка, в котором происходят события, когда два (или более) потока работают с одним и тем же значением. Язык, компилятор, ОС, процессор ... ВСЕ могут играть роль и принимать решение об изменении порядка операций для скорости, практичности или по любой другой причине.
Правильный способ для такого рода вещей - использовать инструменты совместного использования Python ( блокировки
и друзья) или, что еще лучше, передавать данные через очередь вместо того, чтобы делиться ими, например, вот так:
from threading import Thread
from queue import Queue
import time
def thread1(threadname, q):
while True:
a = q.get()
if a is None: return
print a
def thread2(threadname, q):
a = 0
for _ in xrange(10):
a += 1
q.put(a)
time.sleep(1)
q.put(None)
queue = Queue()
thread1 = Thread( target=thread1, args=("Thread-1", queue) )
thread2 = Thread( target=thread2, args=("Thread-2", queue) )
thread1.start()
thread2.start()
thread1.join()
thread2.join()