У функції:
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()