用多个__init__参数inheritancePython元组
以下代码工作:
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)
为什么?
因为元组是不可变的,所以你必须重写__new__
:
python文档
object.__new__(cls[, ...])
调用来创build类
cls
的新实例。__new__()
是一个静态方法(特殊的,所以你不需要这样声明),它将需要实例的类作为它的第一个参数。 其余的参数是传递给对象构造函数expression式(对类的调用)的参数。__new__()
的返回值应该是新的对象实例(通常是cls
一个实例)。典型的实现是通过使用
super(currentclass, cls).__new__(cls[, ...])
来调用超类的__new__()
方法来创build一个新类的实例,然后在返回之前根据需要修改新创build的实例它。如果
__new__()
返回一个cls
实例,则新实例的__init__()
方法将被调用,如__init__(self[, ...])
,其中self是新实例,其余参数与传递给__new__()
。如果
__new__()
没有返回一个cls
实例,那么新实例的__init__()
方法将不会被调用。
__new__()
主要用于允许不可变types的子类(如int
,str
或tuple
)自定义实例创build。 为了自定义类的创build,它也通常在自定义元类中被重载。
要分配元组值,您需要重写__new__
方法:
class Foo(tuple): def __new__ (cls, a, b): return super(Foo, cls).__new__(cls, tuple(b))
参数似乎被tuple类的__init__
实现忽略,但是如果你需要做一些init的东西,你可以这样做:
class Foo(tuple): def __new__ (cls, a, b): return super(Foo, cls).__new__(cls, tuple(b)) def __init__(self, a, b): self.a=a self.b=b if __name__ == '__main__': foo = Foo(None, [3, 4]) print foo print foo.a print foo.b