pythonoopinheritancesupernamedtuple

Inheriting from a namedtuple base class


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? If so, how?


Solution

  • 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]