13518219792

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

创新互联Python教程:contextvars—-上下文变量

contextvars —- 上下文变量


本模块提供了相关API用于管理、存储和访问上下文相关的状态。 ContextVar 类用于声明 上下文变量 并与其一起使用。函数 copy_context() 和类 Context 用于管理当前上下文和异步框架中。

在多并发环境中,有状态上下文管理器应该使用上下文变量,而不是 threading.local() 来防止他们的状态意外泄露到其他代码。

更多信息参见 PEP 567 。

3.7 新版功能.

上下文变量

class contextvars.ContextVar(name[, **, default*])

此类用于声明一个新的上下文变量,如:

 
 
 
 
  1. var: ContextVar[int] = ContextVar('var', default=42)

name 参数用于内省和调试,必需。

调用 ContextVar.get() 时,如果上下文中没有找到此变量的值,则返回可选的仅命名参数 default

重要: 上下文变量应该在顶级模块中创建,且永远不要在闭包中创建。 Context 对象拥有对上下文变量的强引用,这可以让上下文变量被垃圾收集器正确回收。

class contextvars.Token

ContextVar.set() 方法返回 Token 对象。此对象可以传递给 ContextVar.reset() 方法用于将上下文变量还原为调用 set 前的状态。

手动上下文管理

contextvars.copy_context()

返回当前上下文中 Context 对象的拷贝。

以下代码片段会获取当前上下文的拷贝并打印设置到其中的所有变量及其值:

 
 
 
 
  1. ctx: Context = copy_context()
  2. print(list(ctx.items()))

此函数复杂度为 O(1) ,也就是说对于只包含几个上下文变量和很多上下文变量的情况,他们是一样快的。

class contextvars.Context

ContextVars 中所有值的映射。

Context() 创建一个不包含任何值的空上下文。如果要获取当前上下文的拷贝,使用 copy_context() 函数。

Context 实现了 collections.abc.Mapping 接口。

asyncio 支持

上下文变量在 asyncio 中有原生的支持并且无需任何额外配置即可被使用。 例如,以下是一个简单的回显服务器,它使用上下文变量来让远程客户端的地址在处理该客户端的 Task 中可用:

 
 
 
 
  1. import asyncio
  2. import contextvars
  3. client_addr_var = contextvars.ContextVar('client_addr')
  4. def render_goodbye():
  5. # The address of the currently handled client can be accessed
  6. # without passing it explicitly to this function.
  7. client_addr = client_addr_var.get()
  8. return f'Good bye, client @ {client_addr}\n'.encode()
  9. async def handle_request(reader, writer):
  10. addr = writer.transport.get_extra_info('socket').getpeername()
  11. client_addr_var.set(addr)
  12. # In any code that we call is now possible to get
  13. # client's address by calling 'client_addr_var.get()'.
  14. while True:
  15. line = await reader.readline()
  16. print(line)
  17. if not line.strip():
  18. break
  19. writer.write(line)
  20. writer.write(render_goodbye())
  21. writer.close()
  22. async def main():
  23. srv = await asyncio.start_server(
  24. handle_request, '127.0.0.1', 8081)
  25. async with srv:
  26. await srv.serve_forever()
  27. asyncio.run(main())
  28. # To test it you can use telnet:
  29. # telnet 127.0.0.1 8081

分享题目:创新互联Python教程:contextvars—-上下文变量
标题链接:http://cdbrznjsb.com/article/coedpgg.html

其他资讯

让你的专属顾问为你服务