Python: Extending a predefined named tuple
namedtuple, python, python-2.7
Solution
You can subclass a `namedtuple`-produced class, but you need to study the generated class more closely. You'll need to add another `__slots__` attribute with the extra fields, update the `_fields` attribute, create new `__repr__` and `_replace` methods (they hardcode the field list and class name) and add extra `property` objects for the additional fields. See the example in the documentation.
That's all a little too much work. Rather than subclass, I'd just reuse the `somenamedtuple._fields` attribute of the source type:
LookupElement = namedtuple('LookupElement', ReadElement._fields + ('lookups',))
The `field_names` argument to the `namedtuple()` constructor doesn't have to be a string, it can also be a sequence of strings. Simply take the `_fields` and add more elements by concatenating a new tuple.
Demo:
>>> from collections import namedtuple
>>> ReadElement = namedtuple('ReadElement', 'address value')
>>> LookupElement = namedtuple('LookupElement', ReadElement._fields + ('lookups',))
>>> LookupElement._fields
('address', 'value', 'lookups')
>>> LookupElement('addr', 'val', 'lookup')
LookupElement(address='addr', value='val', lookups='lookup')
This does mean that the extended type is not a subclass of the base type. If you must have a class hierarchy, then rather than try to make named tuples fit that model, I'd switch to using dataclasses instead. Dataclasses can serve the same purpose in most usecases named tuples are used for, but can easily be subclassed.
Problem
I have the following named tuple: ``` from collections import namedtuple ReadElement = namedtuple('ReadElement', 'address value') ``` and then I want the following: ``` LookupElement = namedtuple('LookupElement', 'address value lookups') ``` There is duplication between the two namedtuples, how can I subclass ReadElement to contain an additional field? ``` class LookupElement(ReadElement): def __new__(self, address, value, lookups): self = super(LookupElement, self).__new__(address, value) l = list(self) l.append(lookups) return tuple(l) ``` However the tuple is created there an then in the new statement, if I modify self to be a list I will loose type information, how can I avoid this?