如何装饰一堂课?

在Python 2.5中,有没有办法创建装饰类的装饰器?具体来说,我想使用装饰器将成员添加到类中,并更改构造函数以获取该成员的值。


寻找类似以下的内容(在“ Foo类:”上存在语法错误:


def getId(self): return self.__id


class addID(original_class):

    def __init__(self, id, *args, **kws):

        self.__id = id

        self.getId = getId

        original_class.__init__(self, *args, **kws)


@addID

class Foo:

    def __init__(self, value1):

        self.value1 = value1


if __name__ == '__main__':

    foo1 = Foo(5,1)

    print foo1.value1, foo1.getId()

    foo2 = Foo(15,2)

    print foo2.value1, foo2.getId()

我想我真正想要的是在Python中执行类似C#接口的方法。我想我应该改变我的范式。


慕慕森
浏览 335回答 3
3回答

慕桂英4014372

除了类装饰器是否是您的问题的正确解决方案的问题之外:在Python 2.6和更高版本中,有带有@语法的类装饰器,因此您可以编写:@addIDclass Foo:    pass在旧版本中,您可以使用另一种方法:class Foo:    passFoo = addID(Foo)但是请注意,这与函数装饰器的工作原理相同,并且装饰器应返回新(或修改后的原始)类,这不是您在示例中所做的。addID装饰器如下所示:def addID(original_class):    orig_init = original_class.__init__    # Make copy of original __init__, so we can call it without recursion    def __init__(self, id, *args, **kws):        self.__id = id        self.getId = getId        orig_init(self, *args, **kws) # Call the original __init__    original_class.__init__ = __init__ # Set the class' __init__ to the new one    return original_class然后,您可以按照上述方式为Python版本使用适当的语法。但是我同意其他人的观点,如果你想重写继承,继承更适合__init__。

蓝山帝景

没有人解释过您可以动态定义类。因此,您可以有一个装饰器来定义(并返回)一个子类:def addId(cls):    class AddId(cls):        def __init__(self, id, *args, **kargs):            super(AddId, self).__init__(*args, **kargs)            self.__id = id        def getId(self):            return self.__id    return AddId可以在Python 2中使用它(来自Blckknght的评论,它解释了为什么您应该在2.6+中继续这样做):class Foo:    passFooId = addId(Foo)并且在Python 3中是这样的(但要小心super()在类中使用):@addIdclass Foo:    pass所以,你可以有你的蛋糕和吃它-继承和装饰!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python