Ändern eines Konstruktorargumente des namedtuple über Subklassen?
-
28-09-2019 - |
Frage
Ich möchte ein namedtuple
schaffen, die die einzelnen Fahnen in kurzer bitfield darstellt. Ich versuche, es zu Unterklasse, so dass ich die bitfield entpacken kann, bevor das Tupel erstellt wird. Allerdings ist mein aktueller Versuch nicht funktioniert:
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)
Nun, meine Erfahrung mit super()
beschränkt ist und meine Erfahrung mit __new__
ist praktisch nicht vorhanden, so dass ich bin mir nicht ganz sicher, was der (für mich) rätselhafte Fehler TypeError: super.__new__(Status): Status is not a subtype of super
zu machen. Googeln und in die Dokumente zu graben haben nicht nachgegeben etwas zu erleuchten.
Hilfe?
Lösung
Sie haben es fast :-) Es gibt nur zwei kleine Korrekturen:
- Die neue braucht Methode eine zurück Aussage
- Das Super Aufruf sollte zwei Argumente hat, cls und Status
Die resultierende Code sieht wie folgt aus:
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)
Es läuft sauber, so wie du es erwartet hatte:
>>> print Status(47)
Status(started=1, checking=2, start_after_check=4, checked=8, error=0, paused=32, queued=0, loaded=0)
Andere Tipps
würde ich super
vermeiden, wenn Sie explizit auf die Mehrfachvererbung Catering sind (hoffentlich nicht der Fall hier ;-). Tun Sie einfach so etwas wie ...:
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)