半醒着的阳光 2024-10-31 15:15
浏览 4
已结题

python调用带有装饰器的方法不经过装饰器内部

请问:第三个为什么是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
  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 已结题 (查看结题原因) 10月31日
    • 修改了问题 10月31日
    • 创建了问题 10月31日