跳转到主要内容

执行本地化:杀死全局状态(包括线程本地状态)

项目描述

此模块提供了执行本地化,即“xlocal”对象,它实现了一种更受限制的“线程本地”变体。执行本地化允许以类似于真实局部变量的方式按执行方式管理属性

  • 被调用的函数不能更改调用函数的绑定

  • 绑定存在于代码块中(及其调用的所有内容)

xlocal 对象的属性绑定不会泄漏到代码块之外,也不会泄漏到其他 greenlets 线程。相比之下,进程全局和所谓的“线程本地”都不实现上述属性。

让我们看一个基本示例

# content of example.py

from xlocal import xlocal

xcurrent = xlocal()

def output():
    print "hello world", xcurrent.x

if __name__ == "__main__":
    with xcurrent(x=1):
        output()

如果我们执行此模块,output() 函数将看到一个 xcurrent.x==1 绑定

$ python example.py
hello world 1

以下是详细情况:当执行 xcurrent(x=1) 时,它返回一个上下文管理器,该管理器设置/重置 x 属性在 xcurrent 对象上。在同一个线程/greenlet 中,所有由 with-body 触发的代码(在这个例子中只是 output() 函数)都可以访问 xcurrent.x。在 with-body 之外,xcurrent.x 将引发 AttributeError。也不允许直接设置 xcurrent 属性;您必须始终使用 with 语句明确标记其生命周期。这意味着被调用的代码

  • 不能重新绑定调用函数的 xlocal 状态(没有副作用,真好!)

  • xlocal 状态不会泄漏到 with 上下文之外(生命周期控制)

现在另一个模块可以重用示例代码

# content of example_call.py
import example

with example.xcurrent(x=3):
    example.output()

当运行时…

$ python example_call.py
hello world 3

这将会导致example.output()函数打印出在调用with xcurrent(x=3)语句时定义的绑定。

其他线程或greenlets将永远看不到这个绑定;它们甚至可以设置和读取它们自己的独特的对象。这意味着所有的线程/greenlets都可以并发调用一个函数,该函数总是会看到执行特定的属性。

在调用“处理程序”的框架和库中的使用

当调用插件代码或处理程序代码以执行工作,你可能不想传递所有可能需要的状态。而不是使用全局或线程局部,你可以安全地在执行局部中传递这样的状态。以下是一个伪代码示例

xcurrent = xlocal()

def with_xlocal(func, **kwargs):
    with xcurrent(**kwargs):
        func()

def handle_request(request):
    func = gethandler(request)  # some user code
    spawn(with_xlocal(func, request=request))

handle_request将在一个新创建的执行单元中运行用户提供的处理程序函数(例如,spawn可能映射到threading.Thread(...).start()gevent.spawn(...))。通用的with_xlocal辅助器封装了处理程序函数的执行,以便它可以看到绑定。多个spawn可以并发执行,并且将在它们中携带执行特定的请求对象。

值得关注的问题

如果方法记忆了一个执行局部的属性,例如上面的,那么它将保留对确切请求对象的引用,而不是对每个执行的引用。如果你想保留每个执行的局部,你可以这样做,例如

Class Renderer:
    @property
    def request(self):
        return xcurrent.request

这意味着即使实例的生命周期跨越执行单元,渲染器实例也将有一个执行局部对象。

另一个问题是,如果你创建新的执行单元,它们不会隐式继承执行局部。相反,你必须包装你的创建函数来显式设置执行局部,就像我们在上面的“调用处理程序”部分所做的那样。

项目详情


发行历史 发布通知 | RSS源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码发行版

xlocal-0.5.zip (11.0 kB 查看散列)

上传时间 源代码

支持者:

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面