contextvarsContext Variables上下文变量


This module provides APIs to manage, store, and access context-local state. 此模块提供用于管理、存储和访问上下文本地状态的API。The ContextVar class is used to declare and work with Context Variables. ContextVar类用于声明和处理上下文变量The copy_context() function and the Context class should be used to manage the current context in asynchronous frameworks.应使用copy_context()函数和Context类来管理异步框架中的当前上下文。

Context managers that have state should use Context Variables instead of threading.local() to prevent their state from bleeding to other code unexpectedly, when used in concurrent code.当在并发代码中使用时,具有状态的上下文管理器应该使用上下文变量而不是threading.local(),以防止其状态意外泄漏到其他代码。

See also PEP 567 for additional details.其他详细信息,请参阅PEP 567

New in version 3.7.版本3.7中新增。

Context Variables上下文变量

classcontextvars.ContextVar(name[, *, default])

This class is used to declare a new Context Variable, e.g.:此类用于声明一个新的上下文变量,例如:

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

The required name parameter is used for introspection and debug purposes.所需的name参数用于内省和调试目的。

The optional keyword-only default parameter is returned by ContextVar.get() when no value for the variable is found in the current context.当在当前上下文中找不到变量的值时,ContextVar.get()将返回可选的仅限关键字的default参数。

Important: Context Variables should be created at the top module level and never in closures. 上下文变量应该在顶级模块级别创建,而不是在闭包中创建。Context objects hold strong references to context variables which prevents context variables from being properly garbage collected.对象持有对上下文变量的强引用,这会阻止上下文变量被正确地垃圾收集。

name

The name of the variable. This is a read-only property.变量的名称。这是只读属性。

New in version 3.7.1.版本3.7.1中新增。

get([default])

Return a value for the context variable for the current context.返回当前上下文的上下文变量的值。

If there is no value for the variable in the current context, the method will:如果当前上下文中没有变量的值,则该方法将:

  • return the value of the default argument of the method, if provided; or返回方法的default参数的值(如果提供);或

  • return the default value for the context variable, if it was created with one; or如果上下文变量是用一个值创建的,则返回其默认值;或

  • raise a LookupError.引发LookupError

set(value)

Call to set a new value for the context variable in the current context.调用为当前上下文中的上下文变量设置一个新值。

The required value argument is the new value for the context variable.必需的value参数是上下文变量的新值。

Returns a Token object that can be used to restore the variable to its previous value via the ContextVar.reset() method.返回一个Token对象,该对象可用于通过ContextVar.reset()方法将变量恢复到以前的值。

reset(token)

Reset the context variable to the value it had before the ContextVar.set() that created the token was used.将上下文变量重置为使用创建令牌的ContextVar.set()之前的值。

For example:例如:

var = ContextVar('var')
token = var.set('new value')
# code that uses 'var'; var.get() returns 'new value'.
var.reset(token)

# After the reset call the var has no value again, so
# var.get() would raise a LookupError.
classcontextvars.Token

Token objects are returned by the ContextVar.set() method. 对象由ContextVar.set()方法返回。They can be passed to the ContextVar.reset() method to revert the value of the variable to what it was before the corresponding set.它们可以传递给ContextVar.reset()方法,以将变量的值恢复到相应集合之前的值。

var

A read-only property. 只读属性。Points to the ContextVar object that created the token.指向创建令牌的ContextVar对象。

old_value

A read-only property. 只读属性。Set to the value the variable had before the ContextVar.set() method call that created the token. 设置为创建标记的ContextVar.set()方法调用之前变量的值。It points to Token.MISSING is the variable was not set before the call.它指向的Token.MISSING是在调用之前未设置的变量。

MISSING

A marker object used by Token.old_value.Token.old_value使用的标记对象。

Manual Context Management手动上下文管理

contextvars.copy_context()

Returns a copy of the current Context object.返回当前Context对象的副本。

The following snippet gets a copy of the current context and prints all variables and their values that are set in it:以下代码段获取当前上下文的副本,并打印其中设置的所有变量及其值:

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

The function has an O(1) complexity, i.e. works equally fast for contexts with a few context variables and for contexts that have a lot of them.该函数具有O(1)复杂性,即对于具有少量上下文变量的上下文和具有大量上下文变量的语境,其工作速度同样快。

classcontextvars.Context

A mapping of ContextVars to their values.ContextVars到其值的映射。

Context() creates an empty context with no values in it. 创建一个没有值的空上下文。To get a copy of the current context use the copy_context() function.要获得当前上下文的副本,请使用copy_context()函数。

Context implements the collections.abc.Mapping interface.Context实现collections.abc.Mapping接口。

run(callable, *args, **kwargs)

Execute callable(*args, **kwargs) code in the context object the run method is called on. 在调用run方法的上下文对象中执行可调用callable(*args, **kwargs)代码。Return the result of the execution or propagate an exception if one occurred.返回执行结果或传播异常(如果发生)。

Any changes to any context variables that callable makes will be contained in the context object:callable对任何上下文变量所做的任何更改都将包含在上下文对象中:

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'

The method raises a RuntimeError when called on the same context object from more than one OS thread, or when called recursively.当从多个操作系统线程对同一上下文对象调用时,或者当递归调用时,该方法会引发RuntimeError

copy()

Return a shallow copy of the context object.返回上下文对象的浅层副本。

var in context

Return True if the context has a value for var set; return False otherwise.如果上下文具有var集的值,则返回True;否则返回False

context[var]

Return the value of the var ContextVar variable. 返回var ContextVar变量的值。If the variable is not set in the context object, a KeyError is raised.如果未在上下文对象中设置变量,则会引发KeyError

get(var[, default])

Return the value for var if var has the value in the context object. 如果var在上下文对象中具有值,则返回var的值。Return default otherwise. If default is not given, return None.否则返回default。如果未给定default,则返回None

iter(context)

Return an iterator over the variables stored in the context object.在上下文对象中存储的变量上返回迭代器。

len(proxy)

Return the number of variables set in the context object.返回在上下文对象中设置的变量数。

keys()

Return a list of all variables in the context object.返回上下文对象中所有变量的列表。

values()

Return a list of all variables’ values in the context object.返回上下文对象中所有变量值的列表。

items()

Return a list of 2-tuples containing all variables and their values in the context object.返回包含上下文对象中所有变量及其值的2元组列表。

asyncio support

Context variables are natively supported in asyncio and are ready to be used without any extra configuration. asyncio中本机支持上下文变量,无需任何额外配置即可使用。For example, here is a simple echo server, that uses a context variable to make the address of a remote client available in the Task that handles that client:例如,这里有一个简单的echo服务器,它使用上下文变量使远程客户端的地址在处理该客户端的Task中可用:

import asyncio
import contextvars
client_addr_var = contextvars.ContextVar('client_addr')

def render_goodbye():
# The address of the currently handled client can be accessed
# without passing it explicitly to this function.

client_addr = client_addr_var.get()
return f'Good bye, client @ {client_addr}\n'.encode()

async def handle_request(reader, writer):
addr = writer.transport.get_extra_info('socket').getpeername()
client_addr_var.set(addr)

# In any code that we call is now possible to get
# client's address by calling 'client_addr_var.get()'.

while True:
line = await reader.readline()
print(line)
if not line.strip():
break
writer.write(line)

writer.write(render_goodbye())
writer.close()

async def main():
srv = await asyncio.start_server(
handle_request, '127.0.0.1', 8081)

async with srv:
await srv.serve_forever()

asyncio.run(main())

# To test it you can use telnet:
# telnet 127.0.0.1 8081