原文地址:http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213958.html
在threading module中,有一個非常特別的類local。一旦在主線程實例化了一個local,它會一直活在主線程中,并且又主線程啟動的子線程調用這個local實例時,它的值將會保存在相應的子線程的字典中。
我們先看看測試代碼:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Description: test the threading.local class
# Create: 2008-6-4
# Author: MK2[fengmk2@gmail.com]
from threading import local, enumerate, Thread, currentThread
local_data = local()
local_data.name = 'local_data'
class TestThread(Thread):
def run(self):
print currentThread()
print local_data.__dict__
local_data.name = self.getName()
local_data.add_by_sub_thread = self.getName()
print local_data.__dict__
if __name__ == '__main__':
print currentThread()
print local_data.__dict__
t1 = TestThread()
t1.start()
t1.join()
t2 = TestThread()
t2.start()
t2.join()
print currentThread()
print local_data.__dict__
運行結果:
<_MainThread(MainThread, started)>
{'name': 'local_data'}
<TestThread(Thread-1, started)>
{}
{'add_by_sub_thread': 'Thread-1', 'name': 'Thread-1'}
<TestThread(Thread-2, started)>
{}
{'add_by_sub_thread': 'Thread-2', 'name': 'Thread-2'}
<_MainThread(MainThread, started)>
{'name': 'local_data'}
?
主線程中的local_data并沒有被改變,而子線程中的local_data各自都不相同。
怎么這么神奇?local_data具有全局訪問權,主線程,子線程都能訪問它,但是它的值卻是各當前線程有關,究竟什么奧秘在這里呢?
查看了一下local的源代碼,發現就神奇在_path()方法中:
def _patch(self):
key = object.__getattribute__(self, '_local__key')
d = currentThread().__dict__.get(key)
if d is None:
d = {}
currentThread().__dict__[key] = d
object.__setattr__(self, '__dict__', d)
# we have a new instance dict, so call out __init__ if we have
# one
cls = type(self)
if cls.__init__ is not object.__init__:
args, kw = object.__getattribute__(self, '_local__args')
cls.__init__(self, *args, **kw)
else:
object.__setattr__(self, '__dict__', d)
?
每次調用local實例的屬性前,local都會調用這個方法,找到它保存值的地方.
d = currentThread().__dict__.get(key)? 就是這個地方,確定了local_data值的保存位置。所以子線程訪問local_data時,并不是獲取主線程的local_data的值,在子線程 第一次訪問它是,它是一個空白的字典對象,所以local_data.__dict__為 {},就像我們的輸出結果一樣。
如果想在當前線程保存一個全局值,并且各自線程互不干擾,使用local類吧。