2015-02-13 11 views
11

Mam następujący nazwie krotki:Python: Rozszerzanie predefiniowany nazwie krotki

from collections import namedtuple 
ReadElement = namedtuple('ReadElement', 'address value') 

a następnie chcę następujący:

LookupElement = namedtuple('LookupElement', 'address value lookups') 

Jest powielanie między dwoma namedtuples, jak mogę podklasy ReadElement, aby zawrzeć dodatkowe pole?

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) 

jednak krotka jest tam stworzył następnie w nowego oświadczeniu, jeśli mogę zmienić siebie, aby być lista stracę typ informacji, w jaki sposób można tego uniknąć?

Odpowiedz

19

Można utworzyć podklasę klasy produkcyjnej namedtuple, ale trzeba bardziej uważnie studiować wygenerowaną klasę. Będziesz musiał dodać kolejny atrybut __slots__ z dodatkowymi polami, zaktualizować atrybut _fields, utworzyć nowe metody __repr__ i _replace (zakodują listę pól i nazwę klasy) i dodać dodatkowe obiekty property dla dodatkowych pól. Zobacz example in the documentation.

To wszystko za mało pracy. Zamiast podklasy, to bym po prostu ponownie wykorzystać somenamedtuple._fields attribute typu źródło:

LookupElement = namedtuple('LookupElement', ReadElement._fields + ('lookups',)) 

field_names argument konstruktora namedtuple() nie musi być ciąg, może to być również sekwencja ciągów. Po prostu weź _fields i dodaj więcej elementów poprzez konkatenację nowej krotki.

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') 
+0

to dokładnie to, co chciałem, dzięki – Har

+0

To co docs sugerują robi, ale co zrobić, jeśli masz własny namedtuple z pola generowanego? – Ethereal

+0

@ Ethereal: wszystkie klasy namedtuple są niestandardowe. Atrybut '_fields' nadal będzie odzwierciedlał rzeczywiste pola na klasie. –