python - 如何用上下文管理器装饰 Python 函数?
问题描述
给定一个现有的上下文管理器,我想要一个函数装饰器,它会导致执行发生在with
-block 内。
这应该使以下两个代码块等效:
@decorate(contextmanager)
async def f():
...
await f()
async def f():
...
async with contextmanager:
await f()
asyncio.Semaphore(n)
这对于在例如上下文中包装函数很方便。
decorate
标准库中是否已经存在类似的便利实用程序?
解决方案
有ContextDecorator
,您可以创建从它继承的上下文管理器并像这样使用它
from functools import wraps
from contextlib import ContextDecorator
class MyContext(ContextDecorator):
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('in exit')
some_context = MyContext()
@some_context
def foo(x, y):
print(x + y)
foo(5, 3)
但是,我不确定您是否可以将它用于您未编写的现有内容,或者它是否适用于异步内容,在这种情况下,您可以像这样编写一个装饰器:
from functools import wraps
# Some context manager
class MyContext:
def __enter__(self):
print('in enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('in exit')
# Decotator that gets an existing context manager and uses it
def context_decorator(context_manager):
def inner(func):
@wraps(func)
def wrapper(*args, **kwargs):
with context_manager:
return func(*args, **kwargs)
return wrapper
return inner
some_context = MyContext()
@context_decorator(some_context)
def foo(x, y):
print(x + y)
foo(5, 3)
in enter
8
in exit
附言。请注意,对于 asyncio.Semephore 之类的东西,您需要修改要使用的代码async with
以及await
在相关位置
推荐阅读
- google-bigquery - 更新嵌套数组字段 BigQuery
- mysql - 只有当 T1.column2 的值等于 1 时,我才需要带 T1.column1 的值,如果不是打印'禁用'
- excel - Excel VBA using Selenium - click on href link
- java - 在没有 forceRegenerate 的情况下让 maven jaxb2 插件正常工作的问题
- android - Flutter 默认颜色值
- php - 如何使用 Laravel Fortify 创建身份验证锁屏?
- symfony - Symfony 和 FullCalendar,如何从数据库发送数据
- node.js - 如何使用与 Firebase 函数相同的端口设置 Telegram Webhook?
- javascript - 在 javascript 中执行 curl 请求
- java - 在 Netbeans 上编译:“线程“AWT-EventQueue-0”中的异常 java.lang.RuntimeException:无法编译的源代码 - 表达式的非法开始”