Flask上下文管理源码剖析(储备知识)
一. 偏函数
import functools def index(a1,a2): return a1 + a2 # 原来的调用方式 # ret = index(1,23) # print(ret) # 偏函数,帮助开发者自动传递参数 new_func = functools.partial(index,666) ret = new_func(1) print(ret)
二. 执行父类的方法
""" class Base(object): def func(self): print('Base.func') class Foo(Base): def func(self): # 方式一:根据mro的顺序执行方法 # super(Foo,self).func() # 方式二:主动执行Base类的方法 # Base.func(self) print('Foo.func') obj = Foo() obj.func() """ #################################### class Base(object): def func(self): super(Base, self).func() print('Base.func') class Bar(object): def func(self): print('Bar.func') class Foo(Base,Bar): pass # 示例一 # obj = Foo() # obj.func() # print(Foo.__mro__) # 示例二 # obj = Base() # obj.func()
三. 面向对象的特殊方法
class Foo(object): def __init__(self): # self.storage = {} object.__setattr__(self,'storage',{}) #调用父类的__setattr__方法 def __setattr__(self, key, value): print(key,value,self.storage) obj = Foo() obj.xx = 123 ##对象会自动调用__setattr__方法
四. 栈
class Stack(object): def __init__(self): self.data = [] def push(self,val): self.data.append(val) def pop(self): return self.data.pop() def top(self): return self.data[-1] _stack = Stack() _stack.push('神1') _stack.push('神2') print(_stack.pop()) print(_stack.pop())
五. threading.local详解
多线程中,线程间的数据是共享的, 但是每个线程想要有自己的数据该怎么实现? python中的threading.local对象已经实现,其原理是利用线程的唯一标识作为key,数据作为value来保存其自己的数据,以下是demo演示了多个线程同时修改同一变量的值的结果
实现一个多线程demo
import threading from threading import local import time obj = local() def task(i): obj.xxxxx = i time.sleep(2) print(obj.xxxxx,i) for i in range(10): t = threading.Thread(target=task,args=(i,)) t.start()
那么问题来了,我们如何获取一个线程的唯一标记?threading.get_indet()来获取,根据字典自定义一个为每个协程开辟空间进行存取数据。
import time import threading import greenlet DIC = {} def task(i): # ident = threading.get_ident() #这是用get_ident来标记线程 ident = greenlet.getcurrent() #这是用协程来表现 if ident in DIC: DIC[ident]['xxxxx'] = i else: DIC[ident] = {'xxxxx':i } time.sleep(2) print(DIC[ident]['xxxxx'],i) for i in range(10): t = threading.Thread(target=task,args=(i,)) t.start()
加强版的threading.local
import time import threading try: import greenlet get_ident = greenlet.getcurrent except Exception as e: get_ident = threading.get_ident class Local(object): DIC = {} def __getattr__(self, item): ident = get_ident() if ident in self.DIC: return self.DIC[ident].get(item) return None def __setattr__(self, key, value): ident = get_ident() if ident in self.DIC: self.DIC[ident][key] = value else: self.DIC[ident] = {key:value} obj = Local()
为什么说是加强版的threading.local呢?首先代码中先用协程来做数据隔离,如果协程报错再用线程来进行数据隔离。用协程进行数据隔离避免了上下文切换节省
了开销,如果协程报错,在用线程来隔离,这个也实现代码的健壮性。

浙公网安备 33010602011771号