I want to create a namedtuple
which represents the individual flags in a short bitfield. I'm trying to subclass it so that I can unpack the bitfield before the tuple is created. However, my current attempt isn't working:
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)
Now, my experience with super()
is limited and my experience with __new__
is virtually non-existent, so I'm not quite sure what to make of the (to me) enigmatic error TypeError: super.__new__(Status): Status is not a subtype of super
. Googling and digging into the docs haven't yielded anything enlightening.
Help?
count() and . index() , namedtuple classes also provide three additional methods and two attributes. To prevent name conflicts with custom fields, the names of these attributes and methods start with an underscore. In this section, you'll learn about these methods and attributes and how they work.
The NamedTuple is another class, under the collections module. Like the dictionary type objects, it contains keys and that are mapped to some values. In this case we can access the elements using keys and indexes. To use it at first we need to import it the collections standard library module.
Moreover, as namedtuple instances do not have per-instance dictionaries, they are lightweight and require no more memory than regular tuples. This makes them faster than dictionaries.
namedtuple is in the collections library. typename: This is the name of the new tuple subclass. field_names: A sequence of names for each field.
You almost had it :-) There are just two little corrections:
The resulting code looks like this:
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)
It runs cleanly, just like you had expected:
>>> print Status(47) Status(started=1, checking=2, start_after_check=4, checked=8, error=0, paused=32, queued=0, loaded=0)
I'd avoid super
unless you're explicitly catering to multiple inheritance (hopefully not the case here;-). Just do something like...:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With