flask中使用local类去实现数据隔离,在不同的线程中或者协程中都能使其中的数据互不影响
# 应用 在Flask框架中的globals.py文件下,这些全局变量在各个线程,协程中互不影响
# context locals
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
current_app = LocalProxy(_find_app)
request = LocalProxy(partial(_lookup_req_object, 'request'))
session = LocalProxy(partial(_lookup_req_object, 'session'))
g = LocalProxy(partial(_lookup_app_object, 'g'))
而其中用到的就是一个local类
class Local(object):
__slots__ = ('__storage__', '__ident_func__')
def __init__(self):
object.__setattr__(self, '__storage__', {})
object.__setattr__(self, '__ident_func__', get_ident)
...
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}
...
在falsk中local.py代码中的local类的实现...初次看的时候,发觉在_init_函数里面挺有意思的,抽取出来:
def __init__(self):
object.__setattr__(self, '__storage__', {})
object.__setattr__(self, '__ident_func__', get_ident)
为什么要用这种写法呢?
因为在该类中实现的_setattr_方法,会在对该类找不到的实例属性的时候进行调用,当使用self._storange_ = {}的时候就会调用到local类中的_setattr_方法,
那么该如何绕过它而对local实例属性进行设置呢?
——通过基类object的_setattr_方法。
在第一篇说道
[Python中类创建的过程以及元类的理解]https://www.jianshu.com/p/887958727293
所有类的最顶层基类是object,封装了对实例属性访问(_getattr_, _getattribute_)或者设置(_setattr_)的方法,当自定义类没有实现该方法的时候就会调用基类的这些方法,从另一个角度,也可以像在local类里面通过直接用object的方法直接对实例属性进行设置以及访问。