相关文章推荐
爱笑的肉夹馍  ·  Windows ...·  1 年前    · 
聪明的瀑布  ·  KeyError: 'years', ...·  1 年前    · 

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中文社区 ”。