flask框架-下

Local与偏函数

threasing.local

  多个线程修改同一个数据,复制多份变量给每个线程用,为每个线程开辟一块空间进行书籍存储。

不使用therading.local

# 不用local
from threading import Thread
import time
cxw = -1
def task(arg):
    global cxw
    cxw = arg
    # time.sleep(2)
    print(cxw)

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

结果分析:在运行时结果全部显示为9,数据的混乱,当把time.sleep删除后,结果正常打印1,2,3,4....10。

使用threading.local

from threading import Thread
from threading import local
import time
from threading import get_ident
# 特殊的对象
cxw = local()
def task(arg):
    # 对象.val = 1/2/3/4/5
    cxw.value = arg
    time.sleep(2)
    print(cxw.value)
for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()

  使用local()时数据能正常显示,不混乱。

通过字典自定义threaing.local(函数版)

# 线程下 获取id
from threading import get_ident,Thread
import time
storage = {}
def set(k,v):
    index = get_ident()
    if index in storage:
        storage[index][k] = v
    else:
        storage[index] = {k:v}
def get(k):
    index = get_ident()
    return storage[index][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)
    v = obj.get("val")
    print(v)

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

通过setattr和getattr实现

# 反射
# hasattr(object,name) # 判断对象是否拥有某个属性
# setattr(object,name,value) #为对象增加新的属性
# getattr(object,name,default) #从对象中获取某个属性
# delattr(object,name) #从对象中删除某个属性
#
from threading import get_ident,Thread
import time
class Local(object):
    storage = {}
    def __setattr__(self, key, value):
        ident = get_ident()
        if ident in Local.storage:
            Local.storage[ident][key] = value
        else:
            Local.storage[ident] = {key:value}
    def __getattr__(self, key):
        ident = get_ident()
        return Local.storage[ident][key]
obj = 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):
        object.__setattr__(self,'storage',{})
        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()

兼容线程和协程(源码到request中去看,看local的getattr,setattr)

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()
   

以上的几种Local 实现方法是为了推导出以下源码实现:获取get_ident。

源码入口:app.__call__>>>wsgi_>>>push>>>Local>>

partial偏函数

#偏函数的第二个部分(可变参数),按原有函数的参数顺序进行补充,参数将作用在原函数上,最后偏函数返回一个新函数
from functools import partial
def test(a,b,c,d):
    return a+b+c+d

tes=partial(test,1,2) # a=1,b=2 c=3,d=4
print(tes(3,4))
必须遵循传参统一方式,应用场景,传参形式比较随意简便,不必设置默认的变量值。

session源码分析

SecureCookieSessionInterface
    -open_session
    -save_session

请求上下文

蓝图

g对象

 信号

flask-session

猜你喜欢

转载自www.cnblogs.com/Gaimo/p/11853040.html