contextvars
— Context 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上下文变量¶
-
class
contextvars.
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 theContextVar.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.
-
-
class
contextvars.
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 byToken.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)复杂性,即对于具有少量上下文变量的上下文和具有大量上下文变量的语境,其工作速度同样快。
-
class
contextvars.
Context
¶ A mapping ofContextVars
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 theContext实现collections.abc.Mapping
interface.collections.abc.Mapping
接口。-
run
(callable, *args, **kwargs)¶ Execute在调用run方法的上下文对象中执行可调用callable(*args, **kwargs)
code in the context object the run method is called on.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如果上下文具有var集的值,则返回True
if the context has a value for var set; returnFalse
otherwise.True
;否则返回False
。
-
context[var]
Return the value of the var返回varContextVar
variable.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否则返回default。如果未给定default,则返回None
.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