为了账号安全,请及时绑定邮箱和手机立即绑定

如何装饰一堂课?

如何装饰一堂课?

慕慕森 2019-11-23 13:03:26
在Python 2.5中,有没有办法创建装饰类的装饰器?具体来说,我想使用装饰器将成员添加到类中,并更改构造函数以获取该成员的值。寻找类似以下的内容(在“ Foo类:”上存在语法错误:def getId(self): return self.__idclass addID(original_class):    def __init__(self, id, *args, **kws):        self.__id = id        self.getId = getId        original_class.__init__(self, *args, **kws)@addIDclass Foo:    def __init__(self, value1):        self.value1 = value1if __name__ == '__main__':    foo1 = Foo(5,1)    print foo1.value1, foo1.getId()    foo2 = Foo(15,2)    print foo2.value1, foo2.getId()我想我真正想要的是在Python中执行类似C#接口的方法。我想我应该改变我的范式。
查看完整描述

3 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

除了类装饰器是否是您的问题的正确解决方案的问题之外:


在Python 2.6和更高版本中,有带有@语法的类装饰器,因此您可以编写:


@addID

class Foo:

    pass

在旧版本中,您可以使用另一种方法:


class Foo:

    pass


Foo = 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__。


查看完整回答
反对 回复 2019-11-23
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

没有人解释过您可以动态定义类。因此,您可以有一个装饰器来定义(并返回)一个子类:


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:

    pass


FooId = addId(Foo)

并且在Python 3中是这样的(但要小心super()在类中使用):


@addId

class Foo:

    pass

所以,你可以有你的蛋糕和吃它-继承和装饰!


查看完整回答
反对 回复 2019-11-23
  • 3 回答
  • 0 关注
  • 317 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信