Изменение аргументов конструктора namedtuple с помощью подклассов?
Я хочу создать namedtuple
, который представляет отдельные флаги в коротком битовом поле. Я пытаюсь подклассировать его так, чтобы я мог распаковать битовое поле до того, как кортеж будет создан. Однако моя текущая попытка не работает:
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)
Теперь мой опыт работы с super()
ограничен, а мой опыт работы с __new__
практически не существует, поэтому я не совсем уверен, что делать с (для меня) загадочной ошибкой TypeError: super.__new__(Status): Status is not a subtype of super
. Поиск в гугле и копание в документах ничего не дали поучительный.
Помощь?
2 ответа:
У вас почти получилось :-) есть только две небольшие поправки:
- методуnew требуется операторreturn
- вызовsuper должен иметь два аргумента: cls и Status
Полученный код выглядит следующим образом:
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)
Он работает чисто, как вы и ожидали:
>>> print Status(47) Status(started=1, checking=2, start_after_check=4, checked=8, error=0, paused=32, queued=0, loaded=0)
Я бы избегал
super
, если только вы явно не угождаете множественному наследованию (надеюсь, что это не так;-). Просто сделай что-нибудь вроде этого...: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)