In the threading module, there is a very special class local. Once a local is instantiated in the main thread, it will always live in the main thread, and when the sub-thread started by the main thread calls this local instance, the value is saved in the dictionary of the corresponding sub-thread.
Let's first look at the test code:
#!/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, currentThreadlocal_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__
Running result:
<_ 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 '}
The local_data in the main thread is not changed, and the local_data in the subthread is different.
Why is it so amazing? Local_data has global access and can be accessed by the main thread and sub-thread, but its value is related to the current thread. What is the mystery here?
Check the local source code and find that it is magic in the _ path () method:
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)
Each time before calling the attribute of the local instance, the local will call this method to find the place where it saves the value.
D = currentThread (). _ dict _. get (key) is the place where the local_data value is stored. Therefore, when a subthread accesses local_data, it does not obtain the value of local_data of the main thread. When the subthread accesses it for the first time, it is a blank dictionary object, so local_data. _ dict _ is {}, just like our output.
If you want to save a global value in the current thread without interfering with each other, use the local class.
Technorati: python, local, threading, thread