自定义Local,支持线程和协程数据访问
# from threading import Thread # import time # lqz = -1 # def task(arg): # global lqz # lqz = arg # time.sleep(2) # print(lqz) # # for i in range(10): # # 起10个线程 # t = Thread(target=task,args=(i,)) # t.start() # 通过threading.local修改,保证数据安全 # from threading import Thread # from threading import local # import time # from threading import get_ident # # 特殊的local对象,为每个线程copy了一份空间 # lqz = local() # def task(arg): # # 对象.val = 1/2/3/4/5 # # 执行这句话,响应什么方法setattr # # lqz.aa=arg # # lqz['aa']=arg # setitem # lqz.value = arg # time.sleep(2) # print(lqz.value) # # print(lqz.aa) # for i in range(10): # t = Thread(target=task,args=(i,)) # t.start() # 自己定义一个threading.local # from threading import get_ident,Thread # import time # storage = {} # # { # # '123':{val:1} # # '456':{val:2} # # '789':{val:3} # # } # def set(k,v): # # get_ident获取当前线程id # ident = get_ident() # if ident in storage: # # '123':{val:1} 写了这么一条 # storage[ident][k] = v # else: # storage[ident] = {k:v} # def get(k): # ident = get_ident() # return storage[ident][k] # def task(arg): # set('val',arg) # v = get('val') # print(v) # # for i in range(10): # t = Thread(target=task,args=(i,)) # t.start() # 面向对象版 # from threading import get_ident,Thread # import time # class Local(object): # storage = {} # def set(self, k, v): # ident = get_ident() # if ident in Local.storage: # Local.storage[ident][k] = v # else: # Local.storage[ident] = {k: v} # def get(self, k): # ident = get_ident() # return Local.storage[ident][k] # obj = Local() # def task(arg): # obj.set('val',arg) # # obj.val=arg # v = obj.get('val') # print(v) # for i in range(10): # t = Thread(target=task,args=(i,)) # t.start() # 通过getattr和setattr修改 # from threading import get_ident,Thread # import time # class Local(object): # storage = {} # def __setattr__(self, k, v): # ident = get_ident() # if ident in Local.storage: # Local.storage[ident][k] = v # else: # Local.storage[ident] = {k: v} # def __getattr__(self, k): # ident = get_ident() # return Local.storage[ident][k] # obj = Local() # # obj2=Local() # def task(arg): # obj.val = arg # print(obj.val) # for i in range(10): # t = Thread(target=task,args=(i,)) # t.start() # # from threading import get_ident,Thread # import time # class Local(object): # def __init__(self): # # 会直接触发__setattr__,出问题了 # # self.storage={} # # 通过反射,调用父类__setattr__把storage={},放到对象中 # object.__setattr__(self,'storage',{}) # # def __setattr__(self, k, v): # ident = get_ident() # if ident in self.storage: # self.storage[ident][k] = v # else: # self.storage[ident] = {k: v} # def __getattr__(self, k): # ident = get_ident() # return self.storage[ident][k] # obj = Local() # def task(arg): # obj.val = arg # obj.xxx = arg # print(obj.val) # for i in range(10): # t = Thread(target=task,args=(i,)) # t.start() # 支持协程 try: from greenlet import getcurrent as get_ident except Exception as e: from threading import get_ident from threading import Thread import time class Local(object): def __init__(self): object.__setattr__(self,'storage',{}) def __setattr__(self, k, v): ident = get_ident() if ident in self.storage: self.storage[ident][k] = v else: self.storage[ident] = {k: v} def __getattr__(self, k): ident = get_ident() return self.storage[ident][k] obj = Local() def task(arg): obj.val = arg obj.xxx = arg print(obj.val) for i in range(10): t = Thread(target=task,args=(i,)) t.start()