Модификация аргументов конструктора namedtuple с помощью подклассов? - PullRequest
17 голосов
/ 13 августа 2010

Я хочу создать 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 ]

17 голосов
/ 30 ноября 2011

У вас почти это было :-) Есть только две небольшие поправки:

  1. Для метода new требуется return выражение
  2. Вызов 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)
10 голосов
/ 13 августа 2010

Я бы избегал 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)
...