自定义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()
原文地址:https://www.cnblogs.com/xuqidong/p/13122097.html