【问题标题】:python- How can I get value passed to class decorators?python-如何将值传递给类装饰器?
【发布时间】:2021-05-04 17:53:32
【问题描述】:

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

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

我用它来装饰一个类:

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

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

obj = ClassB()

提前致谢。

【问题讨论】:

  • 你确实意识到你正在用一个函数替换你的类,对吧? ClassB 成为函数no_wrap 的另一个名称,因此xy 可以作为ClassB.xClassB.y 访问。 obj 是原始类的一个实例,由函数 ClassB 返回,并且不包含对xy 的引用。

标签: python python-decorators


【解决方案1】:

尝试打印ClassBobj 的目录。

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

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

请注意 xy 如何仅在 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']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-23
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    相关资源
    最近更新 更多