【问题标题】:Limit of decorator as class compared to decorator as function与作为函数的装饰器相比,装饰器作为类的限制
【发布时间】:2020-03-26 07:26:50
【问题描述】:

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

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

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

@addx
class A:
    pass

assert A.x == 10

是否可以编写与类装饰器相同的装饰器?因为类装饰器不能用__init__返回对象本身

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

【问题讨论】:

    标签: python class decorator python-decorators


    【解决方案1】:

    你可以像这样编写一个等价的基于类的装饰器...

    class addx:
        def __new__(self, obj):
            obj.x = 10
            return obj
    
    @addx
    class A:
        pass
    
    assert A.x == 10
    

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

    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
    

    【讨论】:

    • 谢谢你的回答,装饰一个类只是一个例子,但我想知道我是否可以用装饰器基类返回对象本身(假设我想装饰一个函数修改它的名字)。所以唯一的办法就是使用__new__
    猜你喜欢
    • 2011-09-30
    • 2021-06-24
    • 2019-02-20
    • 2011-10-04
    • 2021-07-16
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 2014-02-18
    相关资源
    最近更新 更多