![](/img/trans.png)
[英]TypeError: __init__() takes at least 3 arguments (2 given) when subclassing Model class
[英]Subclassing tuple with multiple __init__ arguments
以下代码有效:
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__
:
object.__new__(cls[, ...])
调用以创建类
cls
的新实例。__new__()
是一个静态方法(特殊情况,因此您不必这样声明),它将实例被请求的类作为其第一个参数。 其余参数是传递给对象构造函数表达式(对类的调用)的参数。__new__()
的返回值应该是新的对象实例(通常是cls
的实例)。典型的实现通过使用具有适当参数的
super(currentclass, cls).__new__(cls[, ...])
调用超类的__new__()
方法,然后在返回之前根据需要修改新创建的实例,来创建super(currentclass, cls).__new__(cls[, ...])
的新实例。它。如果
__new__()
返回cls
的实例,则将调用新实例的__init__()
方法,就像__init__(self[, ...])
,其中self是新实例,其余参数与传递给__new__()
。如果
__new__()
没有返回cls
的实例,则将不会调用新实例的__init__()
方法。
__new__()
主要用于允许不可变类型的子类(例如int
,str
或tuple
)自定义实例创建。 为了自定义类的创建,它通常也被自定义元类覆盖。
要分配元组值,您需要覆盖__new__
方法:
class Foo(tuple):
def __new__ (cls, a, b):
return super(Foo, cls).__new__(cls, tuple(b))
元组类的__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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.