python- 如何将值传递给 class 装饰器?

python- How can I get value passed to class decorators?

我有一个 class 装饰器,它有两个参数如下:

def decoratorB(x: int, y: int): 
    def inner(cls):
        def no_wrap(*args, **kwargs):
            return cls(*args, **kwargs)

        no_wrap.x = x
        no_wrap.y = y
        return no_wrap

    return inner

我用它来装饰一个class这样:

@decoratorB(x=100, y=-100)
class ClassB():
    def func(self, name):
        pass

如何从 ClassB 的对象中获取 x 和 y 的值?

obj = ClassB()

提前致谢。

尝试打印 ClassBobj 的目录。

>>> print(dir(obj))
# ['__class__', ..., 'func']

>>> print(dir(ClassB))
# ['__annotations__', ..., 'x', 'y']

请注意 xy 如何仅作为 class 在 ClassB 中找到,而不是它的实例。还要注意 func 是如何只在实例中找到的。这是因为您如何定义装饰器。我们将属性应用到 no_wrap 而不是 obj 本身。
您可以在 __init__ 中手动设置属性或更改装饰器。

@decoratorB(x=100, y=-100)
class ClassB:
    def __init__(self):
        for attr in dir(ClassB)[35:]: # Get rid of builtin methods so we don't override
            setattr(self, attr, getattr(ClassB, attr, None))
    def func(self, name):
        pass

>>> print(dir(Class())
# ['__class__', ..., 'func', 'x', 'y']

编辑:感谢 chepner 的评论,我意识到我们可以改写装饰器。

我们应该获取 cls 对象并将值分配给对象而不是“副本”。

def decoratorB(x: int, y: int): 
    def inner(cls):
        new = cls
        new.x = x
        new.y = y
        return new
    return inner

>>> print(dir(ClassB))
# ['__class__', 'func', 'x', 'y']

>>> print(dir(ClassB()))
# ['__class__', 'func', 'x', 'y']