我想我还没有理解如何定义从 namedtuple 子类化的类:
from collections import namedtuple
PD = namedtuple('PD', 'x y z')
p1 = PD(0, 'u', 1)
print p1.x #<== this works
class PDsub(PD):
__slots__ = ()
def __new__(cls, x, y, z):
self = super(PDsub, cls).__new__(cls, x, y, z)
return self
def __init__(self, a):
self.x, self.y, self.z = a, a, a
def __str__(self):
return 'Foo'
p2 = PDsub(5) #<== this does not work
此代码引发
TypeError : __new__() takes exactly 4 arguments (2 given)
。任何想法为什么?
最佳答案
实例构造函数 ( __new__
) 和实例初始值设定项 ( __init__
) 都需要接受相同数量的参数。
您的 __new__
需要 4 个参数,但您的 __init__
方法只接受 2 个。调整一个或另一个以接受相同的数字,或在您的 *args
方法中使用 __init__
全能参数。
例如,使用以下 __new__
方法会使事情正常进行:
def __new__(cls, a):
self = super(PDsub, cls).__new__(cls, a, a, a)
return self
在这种情况下,您根本不再需要
__init__
初始值设定项。演示:
>>> from collections import namedtuple
>>> PD = namedtuple('PD', 'x y z')
>>> class PDsub(PD):
... __slots__ = ()
... def __new__(cls, a):
... self = super(PDsub, cls).__new__(cls, a, a, a)
... return self
... def __str__(self):
... return 'Foo'
...
>>> p2 = PDsub(5)
>>> p2.x, p2.y, p2.z
(5, 5, 5)
>>> str(p2)
'Foo'
像元组这样的不可变类型通常使用
__new__
构造函数而不是 __init__
初始值设定项;所有内置的不可变( frozenset
、 str
、 tuple
)都这样做。关于python - 无法初始化子类命名元组的实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12745671/