执行本地化:杀死全局状态(包括线程本地状态)
项目描述
此模块提供了执行本地化,即“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将永远看不到这个
在调用“处理程序”的框架和库中的使用
当调用插件代码或处理程序代码以执行工作,你可能不想传递所有可能需要的状态。而不是使用全局或线程局部,你可以安全地在执行局部中传递这样的状态。以下是一个伪代码示例
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辅助器封装了处理程序函数的执行,以便它可以看到
值得关注的问题
如果方法记忆了一个执行局部的属性,例如上面的
Class Renderer: @property def request(self): return xcurrent.request
这意味着即使实例的生命周期跨越执行单元,渲染器实例也将有一个执行局部
另一个问题是,如果你创建新的执行单元,它们不会隐式继承执行局部。相反,你必须包装你的创建函数来显式设置执行局部,就像我们在上面的“调用处理程序”部分所做的那样。
版权/灵感
这段代码是基于与Armin Ronacher和其他人讨论的结果,以回应我的一条推特。它从Armin的“werzeug.local”模块和其他模块中提取并细化了一些想法。
- 版权:
2012年Holger Krekel,部分Armin Ronacher
- 许可证:
BSD,有关更多详细信息,请参阅LICENSE。
项目详情
xlocal-0.5.zip的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 8ee1c1551294e366a3c307985ea2129e72717556a5736063c0e089c5fb868405 |
|
MD5 | b5450d4841523f92229e08b0844db854 |
|
BLAKE2b-256 | 4f3be7836d2a24926abff5d8bf2f485a0d6f90c2a931c3eaf67a2f45fc605d1f |