[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