今天碰到跟_threading_local有關的問題,居然查不到太多資訊,就自己翻譯一下吧。
_threading_local
index
/usr/local/lib/python2.4/_threading_local.py
Module Docs
Thread-local 對象
(這個模組提供了threading.local類的Python版本,根據使用的Python版本的不同,可能會有更快的版本。你應該總是從threading裡import local類。)
Thread-local對象提供對thread-local資料的管理。
如果你有需要對線程來講是局部的資料,只需建立一個thread-local對象,像這樣使用其屬性:
>>> mydata = local()
>>> mydata.number = 42
>>> mydata.number
42
你也可以訪問local對象的字典:
>>> mydata.__dict__
{'number': 42}
>>> mydata.__dict__.setdefault('widgets', [])
[]
>>> mydata.widgets
[]
關於thread-local對象最重要的就是它的資料對線程是局部的。如果我們像這樣在不同的線程裡訪問該資料:
>>> log = []
>>> def f():
... items = mydata.__dict__.items()
... items.sort()
... log.append(items)
... mydata.number = 11
... log.append(mydata.number)
>>> import threading
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
>>> log
[[], 11]
我們將得到不同的資料。進一步,在另一個線程裡對資料的更改不會影響到當前線程裡的資料:
>>> mydata.number
42
當然,你從一個local對象得到的值,包括__dict__屬性,對任一個線程來說都是當前最新的。因此,你通常都不會想線上程之間為這些值,因為它們只屬於被定義的那個線程。
你可以通過繼承local類來自訂一個local對象:
>>> class MyLocal(local):
... number = 2
... initialized = False
... def __init__(self, **kw):
... if self.initialized:
... raise SystemError('__init__ called too many times')
... self.initialized = True
... self.__dict__.update(kw)
... def squared(self):
... return self.number ** 2
這樣可以支援不同的值、方法和建構函式。注意如果你定義了__init__方法,它會在local對象在不同的線程被使用的時候被調用。這在需要初始化每個線程的字典的時候有用。
現在我們來建立一個local對象:
>>> mydata = MyLocal(color='red')
我們有了不同的number:
>>> mydata.number
2
一個初始化了的color:
>>> mydata.color
'red'
>>> del mydata.color
還有一個處理資料的方法:
>>> mydata.squared()
4
跟以前一樣,我們可以在另一個線程裡訪問資料:
>>> log = []
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
>>> log
[[('color', 'red'), ('initialized', True)], 11]
當前線程的資料不受影響:
>>> mydata.number
2
>>> mydata.color
Traceback (most recent call last):
...
AttributeError: 'MyLocal' object has no attribute 'color'
子類可以定義slot,但是這不是線程局部的。它們線上程之間是共用的:
>>> class MyLocal(local):
... __slots__ = 'number'
>>> mydata = MyLocal()
>>> mydata.number = 42
>>> mydata.color = 'red'
因此,另一個線程:
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
會影響到當前線程:
>>> mydata.number
11
>>> del mydata