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()
posted @ 2019-11-24 21:14  strawberry*  阅读(24)  评论(0编辑  收藏  举报