flask的local的使用,以及local的原理推导

flask的local的使用以及原理的推导

import time

from threading import Thread, local, get_ident # 获取线程的id

# 这是使用local对象的写法,下面我们会分析推导local对象的原理
a = local()

def task(arg):
    a.value = arg
    time.sleep(1)
    print(a.value)


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



#推导1 用函数的形式来模拟local
storage = {}
def set(k,v):
    # 获取线程id
    ident = get_ident()
    if ident in storage:
        # 如果线程id在里面,重新赋值
        storage[ident][k] = v
    else:
        # 不在里面就以线程id为key,k,v为字典存进去
        storage[ident] = {k:v}


def get(k):
    ident = get_ident()
    return storage[ident][k]


def task(arg):
    set('k', arg)
    time.sleep(1)
    v = get('k')
    print(v)


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


# 推导2 面向对象版
class Local:
    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('k', arg)
    time.sleep(1)
    v = obj.get('k')
    print(v)


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


# 推导3 面向对象的setattr,getattr版
class Local:
    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()

def task(arg):
    obj.val = arg  # 对象.属性=属性值走__setattr__方法
    time.sleep(1)
    print(obj.val) # 对象.属性当没有改属性时,走__getattr__方法


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


# 推导4 面向对象,将storage变成对象的属性
class Local(object):

    def __init__(self):
        # 防止getattr出现递归,我们在父类中设置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  # 对象.属性=属性值走__setattr__方法
    time.sleep(1)
    print(obj.val) # 对象.属性当没有改属性时,走__getattr__方法


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

相关推荐