(ab)using NamedTuple

Ethan Furman ethan at stoneleaf.us
Sat May 27 20:02:03 EDT 2017


So I'm getting a list of dictionaries from an ORM, and the dicts have a couple static fields, plus fields requested by 
the user.  For debugging purposes I'd like to show just the portion of the dict requested by the user, and on just one line.

Using the NamedTuple type for aenum [1] I came up with this:

     class FieldsBase(aenum.NamedTuple):
         def __new__(cls, **mapping):
             final = dict([
                     (name, value)
                     for name, value in mapping.items()
                     if name in cls.__fields__
                     ])
             return super(FieldsBase, cls).__new__(cls, **final)

and then in the main code:

     Record = NamedTuple('Record', ('id', 'module', 'xml_id')+fields, type=FieldsBase)
     ....
             if dry_run:
                 echo('%r would be set in ir.model.data' % (Record(**orphan_rec), ))

So I just throw the whole dict at the NamedTuple, it keeps only the fields the user provided, and I get a decent repr:

     Record(name='John Doe', age='37')
     Record(name='Jane Doe', age='39')
     Record(name='Sam Back', age='25')

What are some of the differences between the stdlib's collections.namedtuple and aenum's NamedTuple? [2]

- metaclass-based

- allows variable sized tuple's if requested

     >>> class Record(aenum.NamedTuple):
     ...     _size_ = TupleSize.fixed|minimum|variable

- allows docstring and default values:

     >>> class Point(NamedTuple):
     ...     x = 0, 'horizontal coordinate', 1
     ...     y = 1, 'vertical coordinate', -1
     ...
     >>> class Color(NamedTuple):
     ...     r = 0, 'red component', 11
     ...     g = 1, 'green component', 29
     ...     b = 2, 'blue component', 37
     ...

- easily combinable:

     >>> Pixel = NamedTuple('Pixel', Point+Color)
     >>> Pixel(99, -101, 255, 128, 0)
     Pixel(x=99, y=-101, r=255, g=128, b=0)

--
~Ethan~

[1] https://pypi.python.org/pypi/aenum
[2] I believe the new type module also has a NamedTuple that allows docstrings, but not the rest as far as I know.



More information about the Python-list mailing list