[Python-ideas] namedtuple is not as good as it should be

Christian Tismer tismer at stackless.com
Mon Jun 10 17:27:40 CEST 2013


Hi Raymond,

I have written a simple implementation of something like a
namelesstuple, as a POC.

I did not make generic tuple classes, yet, there is no class generator.
It shows that the result of pickling is quite compact and has only
a single helper function to restore the pickled objects.

What needs to be implemented is

- the unique dict that holds all fieldname tuples
- the class store that hold all generated classes.

And of course the features that make namedtuple nice. ;-)

What I wanted to see is how efficiently this stuff can be pickled.

------------------------------------------------------------

# namelesstuple
# proof of concept for nametuple implementation using
# the identity of the tuple of field names.

from operator import itemgetter as _itemgetter

_tuple = tuple
_repr_template = '{name}=%r'

class _nlt1(tuple):
     __slots__ = ()

     _fields = ('eins', 'zwei', 'drei')

     def __new__(_cls, args):
         return _tuple.__new__(_cls, args)

     eins = property(_itemgetter(0), doc='Alias for field number 0')
     zwei = property(_itemgetter(1), doc='Alias for field number 1')
     drei = property(_itemgetter(2), doc='Alias for field number 2')

     def __repr__(self):
         'Return a nicely formatted representation string'
         fmt = '{}=%r'
         return self._repr_fmt % self

     _repr_fmt =  ', '.join(_repr_template.format(name=name)
                                  for name in _fields)
     _repr_fmt = '(%s)' % _repr_fmt

     def __reduce__(self):
         return (rebuild_namelesstuple, (tuple(self), self._fields))


class _nlt2(tuple):
     __slots__ = ()

     _fields = ('alpha', 'beta', 'gamma')

     def __new__(_cls, args):
         return _tuple.__new__(_cls, args)

     alpha = property(_itemgetter(0), doc='Alias for field number 0')
     beta = property(_itemgetter(1), doc='Alias for field number 1')
     gamma = property(_itemgetter(2), doc='Alias for field number 2')

     def __repr__(self):
         'Return a nicely formatted representation string'
         fmt = '{}=%r'
         return self._repr_fmt % self

     _repr_fmt =  ', '.join(_repr_template.format(name=name)
                                  for name in _fields)
     _repr_fmt = '(%s)' % _repr_fmt

     def __reduce__(self):
         return (rebuild_namelesstuple, (tuple(self), self._fields))


def rebuild_namelesstuple(args, fields):
     # just a dummy for testing pickle
     if fields[0] == 'eins':
         return _nlt1(args)
     else:
         return _nlt2(args)

# quick check
insts = [
     _nlt1((2, 3, 5)),
     _nlt1((7, 8, 9)),
     _nlt2((2, 3, 5)),
     _nlt2((101, 102, 103)),
     ]


import pickletools, pickle
x=pickle.dumps(insts)
pickletools.dis(x)
pickle.loads(x)

-- 
Christian Tismer             :^)   <mailto:tismer at stackless.com>
Software Consulting          :     Have a break! Take a ride on Python's
Karl-Liebknecht-Str. 121     :    *Starship* http://starship.python.net/
14482 Potsdam                :     PGP key -> http://pgp.uni-mainz.de
phone +49 173 24 18 776  fax +49 (30) 700143-0023
PGP 0x57F3BF04       9064 F4E1 D754 C2FF 1619  305B C09C 5A3B 57F3 BF04
       whom do you want to sponsor today?   http://www.stackless.com/



More information about the Python-ideas mailing list