使用多个__init__参数将元组子类化

以下代码有效:


class Foo(tuple):


    def __init__(self, b):

        super(Foo, self).__init__(tuple(b))


if __name__ == '__main__':

    print Foo([3, 4])


$ python play.py 

结果:


play.py:4: DeprecationWarning: object.__init__() takes no parameters

  super(Foo, self).__init__(tuple(b))

(3, 4)

但不是以下内容:


class Foo(tuple):


    def __init__(self, a, b):

        super(Foo, self).__init__(tuple(b))


if __name__ == '__main__':

    print Foo(None, [3, 4])


$ python play.py 

结果:


Traceback (most recent call last):

  File "play.py", line 7, in <module>

    print Foo(None, [3, 4])

TypeError: tuple() takes at most 1 argument (2 given)

为什么?


蛊毒传说
浏览 418回答 2
2回答

一只斗牛犬

因为元组是不可变的,所以您必须改写__new__:python文档object.__new__(cls[, ...])调用以创建class的新实例cls。__new__()是一个静态方法(特殊情况,因此您无需这样声明),它将实例被请求的类作为其第一个参数。其余参数是传递给对象构造函数表达式(对类的调用)的参数。的返回值__new__()应该是新的对象实例(通常是的实例cls)。典型的实现通过__new__()使用super(currentclass, cls).__new__(cls[, ...])带有适当参数的超类的方法来 创建该类的新实例,然后在返回之前根据需要修改新创建的实例。如果__new__()返回的实例&nbsp; cls,则将__init__()调用新实例的 方法__init__(self[, ...]),其中self是新实例,其余参数与传递给的参数相同__new__()。如果__new__()未返回的实例cls,则__init__()不会调用新实例的方法。__new__()主要是用来允许不可改变的类型(如类的子类&nbsp; int,str或tuple)来定制实例创建。为了自定义类的创建,它通常也被自定义元类覆盖。

慕沐林林

要分配元组值,您需要重写__new__方法:class Foo(tuple):&nbsp; &nbsp; def __new__ (cls, a, b):&nbsp; &nbsp; &nbsp; &nbsp; return super(Foo, cls).__new__(cls, tuple(b))__init__元组类的实现似乎忽略了这些参数,但是如果需要执行一些初始化工作,则可以按以下步骤进行操作:class Foo(tuple):&nbsp; &nbsp; def __new__ (cls, a, b):&nbsp; &nbsp; &nbsp; &nbsp; return super(Foo, cls).__new__(cls, tuple(b))&nbsp; &nbsp; def __init__(self, a, b):&nbsp; &nbsp; &nbsp; &nbsp; self.a=a&nbsp; &nbsp; &nbsp; &nbsp; self.b=bif __name__ == '__main__':&nbsp; &nbsp; foo = Foo(None, [3, 4])&nbsp; &nbsp; print foo&nbsp; &nbsp; print foo.a&nbsp; &nbsp; print foo.b
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python