Python:可选参数装饰器作为类的实现

标签 python oop decorator

看完优秀Primer on Python Decorators我想将文章中的一些奇特(高级)装饰器实现为类作为练习。

例如带参数的装饰器示例

def repeat(num_times):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat
    return decorator_repeat

可以像这样实现为一个类

class Repeat:
    def __init__(self, times):
        self.times = times

    def __call__(self, fn):
        def _wrapper(*args, **kwargs):
            for _ in range(self.times):
                result = fn(*args, **kwargs)
            return result
        return _wrapper

但是我似乎无法找到 optional argument decorator example 的类解决方案:

def repeat(_func=None, *, num_times=2):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat

    if _func is None:
        return decorator_repeat
    else:
        return decorator_repeat(_func)

是我,还是那个人很邪恶? XD 很想看到解决方案!

最佳答案

您可以覆盖 __new__ 方法来实现相同的行为:

def __new__(cls, _func=None, *, times=2):
    obj = super().__new__(cls)
    obj.__init__(times)
    if _func is None:
        return obj
    else:
        return obj(_func)

这样两者:

@Repeat
def a():
    print('hi')

和:

@Repeat(times=2)
def a():
    print('hi')

输出:

hi
hi

关于Python:可选参数装饰器作为类的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60946747/

相关文章:

python - 将字典保存到文件 Python

无法使用 macports 安装导入 Python scipy 模块

objective-c - Objective-C 中的脆弱基类是什么?

angularjs - Typescript 类装饰器扩展方法

python - __repr__ 装饰器在子类上失败

python - Python 中的装饰器。如何检查args类型

python - 具有至少 1 个唯一列值的随机 DataFrame 样本

python - 并行线程 python GIL 与 Java

java - Spring Bean 和 Hibernate 表

c# - 我可以找出我正在使用的方法的名称吗?