03 threading.local和高级
Flask的local类知识储备
栈
后进先出,通过列表可以实现一个栈。
v=[11,22,33]
v.append(44)
v.pop()#添加到最后一个并把最后一个先删除
应用场景在 django的drf组件的节流
面向对象
class Foo: #
obj = Foo() obj() # __call__ 面向对象执行对应的call方法
obj[x1] = 123 # __setitem__ obj[x2] # __getitem__ #x1设置值执行对应的x1方法
obj.x1 = 123 # __setattr__ obj.x2 # __getattr__
x1 执行对象的getattr方法
drf中封装request
新的request功能没有可以直接使用旧的request的方法
源码内部执行了getattr 可以直接使用request.方法
request.data
request.POST
错误示例
规避错误使用这个方法
上面两个方式都会触发setattr
通过使用object.__setattr__(self,'storage',{})
线程的唯一标识
import threading
from threading import get_ident
def task():
ident=get_ident()
print(ident)
for i in range(20):
t=threading.Thread(target=task)
t.start()
获取进程的标识
from threading import Thread
def task(name):
print(os.getpid())#主进程的pid
if __name__ == '__main__':
t1=Thread(target=task,args=('海狗',))
t1.start()
print('===主线程')
low版手写threading local
作用:为每一个线程开辟一个独立的内存空间
import threading
"""
storage = {
1111:{'x1':0},
1112:{'x1':1}
1113:{'x1':2}
1114:{'x1':3}
1115:{'x1':4}
}
"""
class Local(object):
def __init__(self):#Storage为键生成一个大字典
object.__setattr__(self,'storage',{})
def __setattr__(self, key, value):
ident = threading.get_ident()
if ident in self.storage:#小字典里面的值 进行改值
self.storage[ident][key] = value
else:
self.storage[ident] = {key:value}
#维护一个键值对
"""
storage = {
1111:{'x1':0},
1112:{'x1':1}
1113:{'x1':2}
1114:{'x1':3}
1115:{'x1':4}
}
"""
def __getattr__(self, item):
ident = threading.get_ident()
if ident not in self.storage:
return
'''
storage = {
1111:{'x1':0},
1112:{'x1':1}
1113:{'x1':2}
1114:{'x1':3}
1115:{'x1':4}
}
'''
return self.storage[ident].get(item)
local = Local()#实例化一个对象
def task(arg):
local.x1 = arg #对象.xxx=arg 会触发__getattr__
print(local.x1)
for i in range(5):#使用多线程生成 多个实例
t = threading.Thread(target=task,args=(i,))
t.start()
升级版字典里面放栈
内部维护一个字典套列表格式
import threading
"""
__storage__ = {
1111:{statck:[]},
1112:{'x1':[]}
1113:{'x1':[]}
1114:{'x1':[]}
1115:{'x1':[]},
1116:{'x1':[]}
}
"""
class Local(object):
def __init__(self):
object.__setattr__(self,'storage',{})
def __setattr__(self, key, value):
ident = threading.get_ident()
if ident in self.storage:
self.storage[ident][key].append(value)
#有就添加进去
else:
#没有就以线程号为键维护一个字典
self.storage[ident] = {key:[value,]}
def __getattr__(self, item):
ident = threading.get_ident()#获取线程号 进行匹配
if ident not in self.storage:
return
return self.storage[ident][item][-1]
#如果有就取出最后一个值 取出栈顶的值
local = Local()
def task(arg):
local.x1 = arg#设置值执行__setattr__
print(local.x1)#设置local.x1 执行__getattr__
for i in range(5):
t = threading.Thread(target=task,args=(i,))
t.start()