Local、LocalStack、LocalManager和LocalProxy 实现协程/线程间数据隔离

本文介绍了Local、LocalStack、LocalManager和LocalProxy在实现协程/线程间数据隔离的角色。Local提供基于id的数据操作封装;LocalStack基于Local创建一个栈,支持入栈、出栈和获取栈顶元素;LocalManager作为装饰器用于werkzeug,执行函数后自动清理;LocalProxy则作为访问Local对象的代理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Local

Local 对 dict 做了一层封装:{id:{...}, id:{...}, ...},每次存储或取出数据时,根据当前id来进行操作。

# get_ident 是优先获取协程id的(若当前环境安装了 greenlet)
class Local(object):
    __slots__ = ("__storage__", "__ident_func__")

    def __init__(self):
        object.__setattr__(self, "__storage__", {
   })           # 存储数据的的地方
        object.__setattr__(self, "__ident_func__", get_ident)   # 获取当前协程或线程id 的函数

    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]   # 获取当前协程中键 为 name 的数据
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        ident = self.__ident_func__()                   # 获取当前协程id
        storage = self.__storage__          
        try:
            storage[ident][name] = value              # 存储数据
        except KeyError:
            storage[ident] = {
   name: value}            # self.__storage__ 中不存在当前 协程id则创建

    def __delattr__(self, name):
        try:
            del self.__storage__[self.__ident_func__()][name]   # 删除数据
        except KeyError:
            raise AttributeError(name)

LocalStack

LocalStack 是基于 Local 实现的,使用 Local 实例在当前协程或线程创建一个名为 stack 的列表,然后根据该列表实现 入栈、出栈以及获取栈顶元素。

class LocalStack(object):
    def __init__(self):
        self._local = Local()    # 创建 Local 对象

    def __release_local__(self):     # 释放当前协程的 数据
        self._local.__release_local__()    

    def _get__ident_func__(self):
        return self._local.__ident_func__

    def _set__ident_func__(self, value):
        object.__setattr__(self._local, "__ident_func__", value)

    __ident_func__ = property(_get__ident_func__, _set__ident_func__)    # 设置、获取 当前协程或线程 唯一标识的方法
    del _get__ident_func__, _set__ident_func__

    def __call__(self):
        def _lookup():
            rv = self.top
            if rv is None:
                <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值