Cannot initiate an instance of a namedtuple subclass

I think I don't know how to define a subclass class from namedtuple:

from collections import namedtuple PD = namedtuple('PD', 'xy 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 

This code raises a TypeError : __new__() takes exactly 4 arguments (2 given) .

Any ideas why?

+3
python namedtuple
source share
2 answers

Both instance constructors ( __new__ ) and your instance initializer ( __init__ ) must accept the same number of arguments.

Your __new__ requires 4 arguments, but your __init__ method accepts only 2. Configure one or the other to accept the same number, or use the *args catch-all argument in your __init__ method.

For example, using the following __new__ method __new__ make everything work:

 def __new__(cls, a): self = super(PDsub, cls).__new__(cls, a, a, a) return self 

in this case, you no longer need your __init__ initializer.

Demo:

 >>> from collections import namedtuple >>> PD = namedtuple('PD', 'xy 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' 

An optional tuple-like type often uses the __new__ constructor instead of the __init__ initializer; all built-in constants ( frozenset , str , tuple ) do this.

+5
source share
 def __new__(cls, x, y, z): p2 = PDsub(5) 

Whenever you create an object for your class, the __new__ (constructor) method is __new__ . So, here your __new__ method requires 4 parameters, but you only passed 2 (* Note: - cls parameter is implicit)

So, either you change __new__ to 2 parameters , or you can change __init__ to accept 4 parameters , and accordingly create your instance by passing 3 parameters (first implicit ..)

+2
source share

All Articles