contextlib --- with 陳述式工具程式¶
This module provides utilities for common tasks involving the with
statement. For more information see also 情境管理器型別 and
With 陳述式的情境管理器.
Utilities¶
Functions and classes provided:
- class contextlib.AbstractContextManager¶
An abstract base class for classes that implement
__enter__()and__exit__(). A default implementation for__enter__()is provided which returnsselfwhile__exit__()is an abstract method which by default returnsNone. See also the definition of 情境管理器型別.在 3.6 版被加入.
- class contextlib.AbstractAsyncContextManager¶
An abstract base class for classes that implement
__aenter__()and__aexit__(). A default implementation for__aenter__()is provided which returnsselfwhile__aexit__()is an abstract method which by default returnsNone. See also the definition of Asynchronous Context Managers.在 3.7 版被加入.
- @contextlib.contextmanager¶
This function is a decorator that can be used to define a factory function for
withstatement context managers, without needing to create a class or separate__enter__()and__exit__()methods.While many objects natively support use in with statements, sometimes a resource needs to be managed that isn't a context manager in its own right, and doesn't implement a
close()method for use withcontextlib.closing.An abstract example would be the following to ensure correct resource management:
from contextlib import contextmanager @contextmanager def managed_resource(*args, **kwds): # Code to acquire resource, e.g.: resource = acquire_resource(*args, **kwds) try: yield resource finally: # Code to release resource, e.g.: release_resource(resource)
The function can then be used like this:
>>> with managed_resource(timeout=3600) as resource: ... # Resource is released at the end of this block, ... # even if code in the block raises an exception
The function being decorated must return a generator-iterator when called. This iterator must yield exactly one value, which will be bound to the targets in the
withstatement'sasclause, if any.At the point where the generator yields, the block nested in the
withstatement is executed. The generator is then resumed after the block is exited. If an unhandled exception occurs in the block, it is reraised inside the generator at the point where the yield occurred. Thus, you can use atry...except...finallystatement to trap the error (if any), or ensure that some cleanup takes place. If an exception is trapped merely in order to log it or to perform some action (rather than to suppress it entirely), the generator must reraise that exception. Otherwise the generator context manager will indicate to thewithstatement that the exception has been handled, and execution will resume with the statement immediately following thewithstatement.contextmanager()usesContextDecoratorso the context managers it creates can be used as decorators as well as inwithstatements. When used as a decorator, a new generator instance is implicitly created on each function call (this allows the otherwise "one-shot" context managers created bycontextmanager()to meet the requirement that context managers support multiple invocations in order to be used as decorators).在 3.2 版的變更: Use of
ContextDecorator.
- @contextlib.asynccontextmanager¶
Similar to
contextmanager(), but creates an asynchronous context manager.This function is a decorator that can be used to define a factory function for
async withstatement asynchronous context managers, without needing to create a class or separate__aenter__()and__aexit__()methods. It must be applied to an asynchronous generator function.一個簡單範例:
from contextlib import asynccontextmanager @asynccontextmanager async def get_connection(): conn = await acquire_db_connection() try: yield conn finally: await release_db_connection(conn) async def get_all_users(): async with get_connection() as conn: return conn.query('SELECT ...')
在 3.7 版被加入.
Context managers defined with
asynccontextmanager()can be used either as decorators or withasync withstatements:import time from contextlib import asynccontextmanager @asynccontextmanager async def timeit(): now = time.monotonic() try: yield finally: print(f'it took {time.monotonic() - now}s to run') @timeit() async def main(): # ... async code ...
When used as a decorator, a new generator instance is implicitly created on each function call. This allows the otherwise "one-shot" context managers created by
asynccontextmanager()to meet the requirement that context managers support multiple invocations in order to be used as decorators.在 3.10 版的變更: Async context managers created with
asynccontextmanager()can be used as decorators.
- contextlib.closing(thing)¶
Return a context manager that closes thing upon completion of the block. This is basically equivalent to:
from contextlib import contextmanager @contextmanager def closing(thing): try: yield thing finally: thing.close()
And lets you write code like this: