2015-02-13 10 views
11

Ho la seguente tupla nome:Python: Estensione di un nome tupla predefinito

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

e poi voglio il seguente:

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

C'è doppioni tra le due namedtuples, come posso sottoclasse ReadElement per contenere un campo aggiuntivo?

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) 

Tuttavia la tupla viene creato lì un poi nella nuova dichiarazione , se modifico sé ad essere un elenco sarò perdere le informazioni sul tipo, come posso evitare questo?

risposta

19

È possibile creare una sottoclasse di una classe prodotta da namedtuple, ma è necessario studiare più da vicino la classe generata. Dovrai aggiungere un altro attributo __slots__ con i campi aggiuntivi, aggiornare l'attributo _fields, creare nuovi metodi __repr__ e _replace (codificano l'elenco dei campi e il nome della classe) e aggiungere altri oggetti property per i campi aggiuntivi. Vedi lo example in the documentation.

Questo è tutto un po 'troppo lavoro. Invece di sottoclasse, avevo appena riutilizzare il somenamedtuple._fields attribute del tipo di fonte:

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

La field_names argomento del costruttore namedtuple() non deve essere una stringa, ma può anche essere una sequenza di stringhe. Basta prendere lo _fields e aggiungere altri elementi concatenando una nuova tupla.

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

questo è esattamente quello che volevo, grazie – Har

+0

Questo è ciò che la documentazione suggeriscono di fare, ma cosa succede se hai un namedtuple con un campo generato? – Ethereal

+0

@Ethereal: tutte le classi namedtuple sono personalizzate. L'attributo '_fields' rifletterà ancora i campi effettivi sulla classe. –

Problemi correlati