请问:第三个为什么是no?怎么实现为yes,即调用时会经过limiter和action装饰器闭包部分的代码,像是直接调用那样
我确定这样的装饰器顺序没有问题
from functools import wraps
from typing import Callable, Any, TypeVar
DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any])
def limiter(times: int = 1):
def decorator(func):
if not hasattr(func, 'action'):
raise AttributeError(
"The function is missing the 'action' attribute."
" Ensure that the @action decorator is applied before @limiter."
)
@wraps(func)
async def wrapper(*args, **kwargs):
if times <= 0:
return 'too many request'
return await func(*args, **kwargs)
return wrapper
return decorator
class A:
def __init__(self):
self._actions = {}
def action(self, name: str) -> Callable[[DecoratedCallable], DecoratedCallable]:
def decorator(func: DecoratedCallable) -> DecoratedCallable:
@wraps(func)
async def wrapper(*args, **kwargs):
return await func(*args, **kwargs)
wrapper.action = name
self._actions[name] = wrapper
return wrapper
return decorator
async def handle(self, action_name: str, *args, **kwargs) -> Any:
if action_name in self._actions:
return await self._actions[action_name](*args, **kwargs)
raise ValueError(f"Action '{action_name}' not found")
a = A()
@limiter(times=0)
@a.action(name="message")
async def message():
return 'hello'
@limiter(times=1)
@a.action(name="gift")
async def gift():
return 'hello'
import asyncio
async def main():
if await message() == 'too many request':
print('yes')
else:
print('no')
if await gift() == 'hello':
print('yes')
else:
print('no')
if await a.handle('message') == 'too many request':
print('yes')
else:
print('no')
if await a.handle('gift') == 'hello':
print('yes')
else:
print('no')
asyncio.run(main())
# yes
# yes
# no
# yes