与作为函数的装饰器相比,装饰器的限制为 class

Limit of decorator as class compared to decorator as function

我想确保我正确理解装饰器 class 的工作原理。

假设我有一个装饰器作为向对象添加属性的函数

def addx(obj):
    obj.x = 10
    return obj

@addx
class A:
    pass

assert A.x == 10

是否可以编写与 class 装饰器相同的装饰器?因为 class 装饰器不能 return 对象本身 __init__

class addx:
    def __init__(self, obj):
        obj.x = 10
        # ???

你可以像这样写一个等效的基于 class 的装饰器...

class addx:
    def __new__(self, obj):
        obj.x = 10
        return obj

@addx
class A:
    pass

assert A.x == 10

...但我认为这对您没有任何帮助。当您的目标是修改 class A 的对象而不是 class A 本身时,基于 class 的装饰器的实用性变得更加明显。比较以下两个装饰器,一个基于函数,一个基于 class:

def addx_func(kls):
    def wrapper():
        res = kls()
        res.x = 10
        return res

    return wrapper


class addx_class:
    def __init__(self, kls):
        self.kls = kls

    def __call__(self):
        res = self.kls()
        res.x = 10
        return res


@addx_func
class A:
    pass


@addx_class
class B:
    pass


a = A()
assert a.x == 10

b = B()
assert b.x == 10