Python 3.7 于2018年6月27日发布,本篇文章将对其中新增模块contextvars 做初步介绍,为读者勾勒一个大概轮廓。
资料来源: Python 3.7 文档、源码。
1、contextvars是什么
2、类与方法
3、如何理解上下文
一、contextvars是什么
这个模块提供了一组接口,可用于管理、储存、访问 局部上下文的状态。
主要用于在异步环境中管理上下文变量。
二、类与方法
1、ContextVar(name[, *, default])
这个类用于表示一个上下文变量。
参数:
name
: 必要位参; 用于检验和Debug.
default
: 默参,且只能用keyword方式指定; 用于设定这个上下文变量的默认值。
属性:
name
:只读特性。
get([default])
:返回该上下文变量的值。未指定默认值且上下文变量无默认值时,抛出
LookupError
。
set(value)
:设置上下文变量的值,返回一个与变量当前值相关的Token对象,可用于重置上下文变量的值到该次set之前。
reset(token)
:使用token重置上下文变量的值。
from contextvars
import
*
2、Token
属性:
var
: 只读特性,指向创建它的上下文变量。
old_value
: 只读特性,保存set之前的上下文变量的值。如果值为空,该特性指向
Token.MISSING
.
3、Context
类型:
Mapping
Key
:
ContextVar
Value
:上下文变量的值
属性:
copy()
:返回
Context
的浅拷贝。
run(callable, *args, **kwargs)
:在该上下文中运行
callable(args, *kwargs)
.
当多线程同时执行
run
时,抛出
RuntimeError
.
当递归地执行
run
时,也会抛出
RuntimeError
.
同一个
Context
,在同一时刻只能有一个
run
方法运行。
PS:多进程显然不在考虑范围内。
文档示例:
var
= ContextVar(
'var'
)
var
.
set
(
'spam'
)
这里给出我的理解:
作用域规定了对象访问权,而上下文规定了上下文变量值访问权。
我们用
ContextVar
表示上下文变量,而具体的值存储在
Context
中。所以
Context
实现为
ContextVar->Value
的
Mapping
。在不同的上下文中,同一个上下文变量的值可以不同。
如果作用域中没有
ContextVar
,你是无法访问或修改
ContextVar
的,文档中建议在模块级别定义
ContextVar
也是这个原因。
Q:定义
ContextVar
时发生了什么?
A:新建了一个对象,仅此而已,上下文中没有保存它。当
ContextVar
被set后,上下文中才会有它。
Q:访问或修改
ContextVar
时发生了什么?
A:访问
ContextVar
时,实际上是在当前上下文中查表,返回当前上下文中
ContextVar
的值。修改同理,实际上是改表。(在源码中还有cache,这里不作说明)
Q:Context机制如何实现?
A:Context与ThreadState相关,进入上下文时“占据”当前线程,退出时“放弃”当前线程。
contextvars为异步而生,上下文对象将简化asyncio的复杂操作,给异步程序的编写带来方便,推荐高级玩家使用。
原文发布时间为:2018-10-14
本文作者:Nugine
本文来自云栖社区合作伙伴“
Python中文社区
”,了解相关信息可以关注“
Python中文社区
”。