Inheriting from a namedtuple base class
Solution 1
You can, but you have to override __new__
which is called implicitly before __init__
:
class Z(X):
def __new__(cls, a, b, c, d):
self = super(Z, cls).__new__(cls, a, b, c)
self.d = d
return self
>>> z = Z(1, 2, 3, 4)
>>> z
Z(a=1, b=2, c=3)
>>> z.d
4
But d
will be just an independent attribute!
>>> list(z)
[1, 2, 3]
Solution 2
I think you can achieve what you want by including all of the fields
in the original named tuple, then adjusting the number of arguments
using __new__
as schwobaseggl suggests above. For instance, to address
max's case, where some of the input values are to be calculated
rather than supplied directly, the following works:
from collections import namedtuple
class A(namedtuple('A', 'a b c computed_value')):
def __new__(cls, a, b, c):
computed_value = (a + b + c)
return super(A, cls).__new__(cls, a, b, c, computed_value)
>>> A(1,2,3)
A(a=1, b=2, c=3, computed_value=6)
Solution 3
I came here with the exact same problem, just two years later.
I personally thought that the @property
decorator would fit in here better:
from collections import namedtuple
class Base:
@property
def computed_value(self):
return self.a + self.b + self.c
# inherits from Base
class A(Base, namedtuple('A', 'a b c')):
pass
cls = A(1, 2, 3)
print(cls.computed_value)
# 6
Comments
-
alvas almost 3 years
This question is asking the opposite of Inherit namedtuple from a base class in python , where the aim is to inherit a subclass from a namedtuple and not vice versa.
In normal inheritance, this works:
class Y(object): def __init__(self, a, b, c): self.a = a self.b = b self.c = c class Z(Y): def __init__(self, a, b, c, d): super(Z, self).__init__(a, b, c) self.d = d
[out]:
>>> Z(1,2,3,4) <__main__.Z object at 0x10fcad950>
But if the baseclass is a
namedtuple
:from collections import namedtuple X = namedtuple('X', 'a b c') class Z(X): def __init__(self, a, b, c, d): super(Z, self).__init__(a, b, c) self.d = d
[out]:
>>> Z(1,2,3,4) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __new__() takes exactly 4 arguments (5 given)
The question, is it possible to inherit namedtuples as a base class in Python? Is so, how?