flask上下文管理相关 - threading.local 以及原理剖析

threading.local

面向对象相关: setattr/getattr

class Foo(object):
    pass

obj = Foo()
obj.x1 = 123 
# object.__setattr__(obj,'x1',123)

print(obj.x1) 
# object.__getattr__(obj,'x1')

Local类的模拟

简易版

class Local(object):
    def __init__(self):
        # self.storage = {}
        object.__setattr__(self,'storage',{})

    def __setattr__(self, key, value):
        self.storage[key] = value

    def __getattr__(self, item):
        return self.storage[item]

obj = Local()

obj.x1 = 123

print(obj.x1)

升级版

import threading
"""
{
    1231:{x1:0},
    1432:{x1:1},
    ...
    5321:{x1:9}
}
"""
class Local(object):
    def __init__(self):
        # self.storage = {}
        object.__setattr__(self,'storage',{})

    def __setattr__(self, key, value):
        # self.storage[key] = value
        ident = threading.get_ident() # 1233
        if ident in self.storage:
            self.storage[ident][key] = value
        else:
            self.storage[ident] = {key:value}

    def __getattr__(self, item):
        ident = threading.get_ident()
        return self.storage[ident][item]

obj = Local()

def task(arg):
    obj.x1 = arg
    print(obj.x1)

for i in range(10):
    t = threading.Thread(target=task,args=(i,))
    t.start()

源码

class Local(object):
    __slots__ = ("__storage__", "__ident_func__")

    def __init__(self):
        object.__setattr__(self, "__storage__", {})
        object.__setattr__(self, "__ident_func__", get_ident)

    def __iter__(self):
        return iter(self.__storage__.items())

    def __call__(self, proxy):
        """Create a proxy for a name."""
        return LocalProxy(self, proxy)

    def __release_local__(self):
        self.__storage__.pop(self.__ident_func__(), None)

    def __getattr__(self, name):
        try:
            return self.__storage__[self.__ident_func__()][name]
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][name] = value
        except KeyError:
            storage[ident] = {name: value}

    def __delattr__(self, name):
        try:
            del self.__storage__[self.__ident_func__()][name]
        except KeyError:
            raise AttributeError(name)

猜你喜欢

转载自www.cnblogs.com/jjzz1234/p/12037050.html