このシナリオでは:
async def foo(f):
async def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
@foo
async def boo(*args, **kwargs):
pass
booデコレータのデコレータとしてのfooの呼び出しは非同期呼び出しですか?
-最初の編集:また、デコレータとしてコルーチンの呼び出しチェーンをどのように処理しますか?
@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
_
2つのデコレータとして
_@foo()
@boo()
async def work(*args):
pass
_
foo
はwork
コルーチンをラップしているため、両方のデコレータでawait
func(*arg)
を使用することが重要です。
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が非同期関数の場合、type(main。boo)は関数オブジェクトではなくコルーチンオブジェクトになります。しかし、fooが通常の同期関数である場合は、すぐに評価され、main。booが返されるラッパーになります。
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