In una funzione:
a += 1
sarà interpretato dal compilatore come assign to a => Create local variable a
, che non è quello che vuoi. Probabilmente fallirà con un a not initialized
errore poiché il (locale) a non è stato effettivamente inizializzato:
>>> 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
Potresti ottenere ciò che desideri con la global
parola chiave (molto disapprovata e per buone ragioni) , in questo modo:
>>> def f():
... global a
... a += 1
...
>>> a
1
>>> f()
>>> a
2
In generale, tuttavia, dovresti evitare di utilizzare variabili globali che diventano estremamente rapidamente fuori controllo. E questo è particolarmente vero per i programmi multithread, dove non hai alcun meccanismo di sincronizzazione per thread1
sapere quando a
è stato modificato. In breve: i thread sono complicati e non ci si può aspettare di avere una comprensione intuitiva dell'ordine in cui si verificano gli eventi quando due (o più) thread lavorano sullo stesso valore. Il linguaggio, il compilatore, il sistema operativo, il processore ... possono TUTTI svolgere un ruolo e decidere di modificare l'ordine delle operazioni per velocità, praticità o per qualsiasi altro motivo.
Il modo corretto per questo genere di cose è usare gli strumenti di condivisione di Python ( lucchetti
e amici), o meglio, comunicare i dati tramite una coda invece di condividerli, ad esempio in questo modo:
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()