Python3.7 contextvars 初探

简介:

简述

Python 3.7 于2018年6月27日发布,本篇文章将对其中新增模块contextvars 做初步介绍,为读者勾勒一个大概轮廓。

资料来源: Python 3.7 文档、源码。

1、contextvars是什么
2、类与方法
3、如何理解上下文
4、总结

一、contextvars是什么

这个模块提供了一组接口,可用于管理、储存、访问 局部上下文的状态。

主要用于在异步环境中管理上下文变量。

二、类与方法

1、ContextVar(name[, *, default])

这个类用于表示一个上下文变量。

参数:
name: 必要位参; 用于检验和Debug.

default: 默参,且只能用keyword方式指定; 用于设定这个上下文变量的默认值。

属性:
name:只读特性。

get([default]):返回该上下文变量的值。未指定默认值且上下文变量无默认值时,抛出LookupError

set(value):设置上下文变量的值,返回一个与变量当前值相关的Token对象,可用于重置上下文变量的值到该次set之前。

reset(token):使用token重置上下文变量的值。

示例:


from contextvars import *

var= ContextVar('var')

x=[1]
var.set(x)

y=var.get()
print(f'x: {id(x)},y: {id(y)},{id(x)==id(y)}')

y=var.get()
print(f'x: {id(x)},y: {id(y)},{id(x)==id(y)}')


z=[2]

token=var.set(z)
print(f'z: {var.get()}')

var.reset(token)

y=var.get()
print(f'x: {id(x)},y: {id(y)},{id(x)==id(y)}')

输出:


x: 2459227742792,y: 2459227742792,True
x: 2459227742792,y: 2459227742792,True
z: [2]
x: 2459227742792,y: 2459227742792,True

2、Token

属性:
var: 只读特性,指向创建它的上下文变量。

old_value: 只读特性,保存set之前的上下文变量的值。如果值为空,该特性指向Token.MISSING.

3、Context

类型:Mapping

KeyContextVar

Value:上下文变量的值

属性:
copy():返回Context的浅拷贝。

run(callable, *args, **kwargs):在该上下文中运行callable(args, *kwargs).

当多线程同时执行run时,抛出RuntimeError.

当递归地执行run时,也会抛出RuntimeError.

同一个Context,在同一时刻只能有一个run方法运行。

PS:多进程显然不在考虑范围内。

文档示例:


var = ContextVar('var')
var.set('spam')

def main():
# 'var' was set to 'spam' before
# calling 'copy_context()' and 'ctx.run(main)', so:
# var.get() == ctx[var] == 'spam'

var.set('ham')

# Now, after setting 'var' to 'ham':
# var.get() == ctx[var] == 'ham'

ctx = copy_context()

# Any changes that the 'main' function makes to 'var'
# will be contained in 'ctx'.
ctx.run(main)

# The 'main()' function was run in the 'ctx' context,
# so changes to 'var' are contained in it:
# ctx[var] == 'ham'

# However, outside of 'ctx', 'var' is still set to 'spam':
# var.get() == 'spam'

4、模块方法:copy_context()
返回当前上下文的拷贝。

时间复杂度: O(1)。因为在C源码中,这个函数只做了新建对象和指针复制。

不管当前上下文有多臃肿,copy_context()的消耗都是不变的。

三、如何理解上下文

自己动手写一些小程序试验一下是最好的方法。

这里给出我的理解:

作用域规定了对象访问权,而上下文规定了上下文变量值访问权。

我们用ContextVar表示上下文变量,而具体的值存储在Context中。所以Context实现为ContextVar->ValueMapping。在不同的上下文中,同一个上下文变量的值可以不同。

如果作用域中没有ContextVar,你是无法访问或修改ContextVar的,文档中建议在模块级别定义ContextVar也是这个原因。

Q & A
Q:定义ContextVar时发生了什么?

A:新建了一个对象,仅此而已,上下文中没有保存它。当ContextVar被set后,上下文中才会有它。

Q:访问或修改ContextVar时发生了什么?

A:访问ContextVar时,实际上是在当前上下文中查表,返回当前上下文中ContextVar的值。修改同理,实际上是改表。(在源码中还有cache,这里不作说明)

Q:Context机制如何实现?

A:Context与ThreadState相关,进入上下文时“占据”当前线程,退出时“放弃”当前线程。

四、总结

contextvars为异步而生,上下文对象将简化asyncio的复杂操作,给异步程序的编写带来方便,推荐高级玩家使用。


原文发布时间为:2018-10-14

本文作者:Nugine

本文来自云栖社区合作伙伴“Python中文社区”,了解相关信息可以关注“Python中文社区”。

相关文章
|
Java 开发工具 数据库
|
4月前
|
人工智能 自然语言处理 JavaScript
Playwright MCP浏览器自动化指南:让AI精准理解你的命令
本文介绍如何结合Playwright与MCP协议实现自然语言驱动的网页自动化操作。通过配置MCP服务器,AI助手可直接操控浏览器完成信息获取、表单填写等复杂任务,显著降低自动化技术门槛,提升操作效率。
|
6月前
|
存储 人工智能 资源调度
MCP协议深度集成:生产级研究助手架构蓝图
本文详解基于LangGraph与MCP协议构建研究助手的技术方案,涵盖双服务器集成、状态化智能体设计与用户元命令控制,助你掌握生产级代理系统开发要点。
542 1
|
4月前
|
人工智能 API 调度
我用 n8n 教自动化,结果自己在干最蠢的活
作者本为学员免费开通n8n账号,却因频繁手动操作陷入效率困境。起初尝试全自动流程,反被滥用;最终引入“人在回路”(HITL)机制,结合自动化与人工审核,用飞书审批实现高效协作。真正高效的自动化,是让机器处理重复工作,人类专注核心决策。
|
安全 Go 开发者
使用 contextvars 管理上下文变量
使用 contextvars 管理上下文变量
402 1
|
存储 人工智能 安全
OSS 深度解析:Data + AI 时代的对象存储
在 Data + AI 时代,随着大数据分析和 AI/ML 工作负载的进一步融合,对象存储 OSS 作为面向 AI 时代的数据基础设施,迎来了新的挑战与创新机遇。本话题我们将会介绍对象存储的能力创新,深度解读对象存储在实现稳定、安全、高性能和低成本背后的技术进展,并展望未来 AI 驱动趋势下的技术发展方向。
1927 2
|
人工智能 自然语言处理 安全
关于claude怎么下载?这篇文章告诉你答案!
Claude 是 Anthropic 公司开发的一款大型语言模型,被誉为下一代 AI 助手 🤖。它拥有强大的文本处理能力,能够进行对话、写作、翻译、总结等多种任务 📝。
|
网络协议 Python
深度剖析Python Socket:从入门到精通,网络编程不再是难题!
【7月更文挑战第27天】在Python中,Socket编程是网络通信的核心。本文从Socket基础概念入手,介绍其作为网络通信端点的作用,并区分TCP(面向连接)与UDP(无连接)。通过示例代码展示如何创建TCP服务器及客户端:服务器监听12345端口,接收并回显客户端消息;客户端则连接服务器并发送消息,接收服务器回应。代码涵盖socket创建、连接管理及数据收发等关键步骤,并强调异常处理与数据编码的重要性。掌握这些基础知识,即可轻松开展网络编程项目。
381 0
|
消息中间件 安全 Python
Python日志管理之Loguru
Python日志管理之Loguru
|
数据采集 JSON 人工智能
Qwen2-Math开源!初步探索数学合成数据生成!
阿里通义团队开源新一代数学模型Qwen2-Math,包含1.5B、7B、72B三个参数的基础模型和指令微调模型。