একটি অনুষ্ঠানে:
a += 1
সংকলক দ্বারা ব্যাখ্যা করা হবে assign to a => Create local variable a
, যা আপনি চান তা নয়। এটি সম্ভবত কোনও a not initialized
ত্রুটির সাথে ব্যর্থ হবে যেহেতু (স্থানীয়) সত্যিকার অর্থে আরম্ভ করা হয়নি:
>>> 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
সংশোধন হয়েছে তা জানার জন্য কোনও সিঙ্ক্রোনাইজেশন প্রক্রিয়া নেই । সংক্ষেপে: থ্রেডগুলি জটিল , এবং যখন দুটি (বা ততোধিক) থ্রেড একই মূল্যে কাজ করে তখন ঘটনাগুলি ক্রম ক্রম সম্পর্কে অন্তর্নিহিত বোঝার আশা করতে পারবেন না। ভাষা, সংকলক, ওএস, প্রসেসর ... সবই ভূমিকা নিতে পারে এবং গতি, ব্যবহারিকতা বা অন্য কোনও কারণে ক্রিয়াকলাপের ক্রমটি সংশোধন করার সিদ্ধান্ত নিতে পারে।
এই জাতীয় জিনিসটির যথাযথ উপায় হল পাইথন ভাগ করে নেওয়ার সরঞ্জামগুলি ( লক
এবং বন্ধু) ব্যবহার করা, বা আরও ভাল, কোনও সারির মাধ্যমে ডেটা ভাগ করার পরিবর্তে ডেটা যোগাযোগ করা, যেমন:
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()