Modifica argomenti del costruttore di una sottoclasse namedtuple via?
-
28-09-2019 - |
Domanda
Voglio creare un namedtuple
che rappresenta i singoli bandiere in un breve campo di bit. Sto cercando di sottoclasse in modo che posso disfare il campo di bit prima della creazione della tupla. Tuttavia, il mio tentativo attuale non funziona:
class Status(collections.namedtuple("Status", "started checking start_after_check checked error paused queued loaded")):
__slots__ = ()
def __new__(cls, status):
super(cls).__new__(cls, status & 1, status & 2, status & 4, status & 8, status & 16, status & 32, status & 64, status & 128)
Ora, la mia esperienza con super()
è limitata e la mia esperienza con __new__
è praticamente inesistente, quindi non sono del tutto sicuro di cosa fare della (per me) enigmatica TypeError: super.__new__(Status): Status is not a subtype of super
errore. Googling e scavare i documenti non hanno dato nulla di illuminante.
Aiuto?
Soluzione
È quasi avuta :-) Ci sono solo due piccole correzioni:
- Il nuovo metodo ha bisogno di un ritorno istruzione
- Il Super chiamata dovrebbe avere due argomenti, CLS e Stato
Gli sguardi codice risultante come questo:
import collections
class Status(collections.namedtuple("Status", "started checking start_after_check checked error paused queued loaded")):
__slots__ = ()
def __new__(cls, status):
return super(cls, Status).__new__(cls, status & 1, status & 2, status & 4, status & 8, status & 16, status & 32, status & 64, status & 128)
Funziona in modo pulito, proprio come avevi previsto:
>>> print Status(47)
Status(started=1, checking=2, start_after_check=4, checked=8, error=0, paused=32, queued=0, loaded=0)
Altri suggerimenti
Eviterei super
meno che non siate esplicitamente catering per ereditarietà multipla (si spera non il caso qui ;-). Basta fare una cosa del genere ...:
def __new__(cls, status):
return cls.__bases__[0].__new__(cls,
status & 1, status & 2, status & 4,
status & 8, status & 16, status & 32,
status & 64, status & 128)