在这种情况下:
async def foo(f):
async def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
@foo
async def boo(*args, **kwargs):
pass
是调用foo作为boo decorator和异步调用的装饰器吗?
- 首先编辑: 另外如何处理调用链的协同作为装饰器?
答案 0 :(得分:15)
感谢@ blacknght的评论,考虑
def foo():
def wrapper(func):
@functools.wraps(func)
async def wrapped(*args):
# Some fancy foo stuff
return await func(*args)
return wrapped
return wrapper
和
def boo():
def wrapper(func):
@functools.wraps(func)
async def wrapped(*args):
# Some fancy boo stuff
return await func(*args)
return wrapped
return wrapper
作为两个装饰者,
@foo()
@boo()
async def work(*args):
pass
当foo
正在包裹work
协程时,关键是await
两个装饰器中的func(*arg)
。
答案 1 :(得分:2)
def foo(f):
async def wrapper(*args, **kwargs):
return await f(*args, **kwargs)
return wrapper
@foo
async def boo(*args, **kwargs):
pass
您的装饰器需要正常运行,然后才能正常工作。
在评估装饰器时,python将以函数为参数执行该方法。
@foo
async def boo():
pass
评估为:
__main__.boo = foo(boo)
如果foo是一个异步函数,则类型( main .boo)将是协程对象,而不是函数对象。但是,如果foo是常规的synch函数,它将立即求值,而 main .boo将是返回的包装器。
答案 2 :(得分:1)
这是使用decorator
库的另一种方法(即首先使用pip install decorator
):
import asyncio
import decorator
@decorator.decorator
async def decorate_coro(coro, *args, **kwargs):
try:
res = await coro(*args, **kwargs)
except Exception as e:
print(e)
else:
print(res)
@decorate_coro
async def f():
return 42
@decorate_coro
async def g():
return 1 / 0
async def main():
return await asyncio.gather(f(), g())
if __name__ == '__main__':
asyncio.run(main())
输出:
42
division by zero