[Python-ideas] a new namedtuple
Nick Coghlan
ncoghlan at gmail.com
Tue Jul 18 09:29:47 EDT 2017
On 18 July 2017 at 14:31, Guido van Rossum <guido at python.org> wrote:
> On Mon, Jul 17, 2017 at 6:25 PM, Eric Snow <ericsnowcurrently at gmail.com>
> wrote:
>>
>> On Mon, Jul 17, 2017 at 6:01 PM, Ethan Furman <ethan at stoneleaf.us> wrote:
>> > Guido has decreed that namedtuple shall be reimplemented with speed in
>> > mind.
>>
>> FWIW, I'm sure that any changes to namedtuple will be kept as minimal
>> as possible. Changes would be limited to the underlying
>> implementation, and would not include the namedtuple() signature, or
>> using metaclasses, etc. However, I don't presume to speak for Guido
>> or Raymond. :)
>
>
> Indeed. I referred people here for discussion of ideas like this:
>
>>>> a = (x=1, y=0)
In that vein, something I'll note that *wasn't* historically possible
due to the lack of keyword argument order preservation is an
implementation that implicitly defines anonymous named tuple types
based on the received keyword arguments.
Given Python 3.6+ though, this works:
from collections import namedtuple
def _make_named_tuple(*fields):
cls_name = "_ntuple_" + "_".join(fields)
# Use the module globals as a cache for pickle compatibility
namespace = globals()
try:
return namespace[cls_name]
except KeyError:
cls = namedtuple(cls_name, fields)
return namespace.setdefault(cls_name, cls)
def ntuple(**items):
cls = _make_named_tuple(*items)
return cls(*items.values())
>>> p1 = ntuple(x=1, y=2)
>>> p2 = ntuple(x=4, y=5)
>>> type(p1) is type(p2)
True
>>> type(p1)
<class '__main__.ntuple_x_y'>
That particular approach isn't *entirely* pickle friendly (since
unpickling will still fail if a suitable type hasn't been defined in
the destination process yet), but you can fix that by way of playing
games with setting cls.__qualname__ to refer to an instance of a
custom class that splits "_ntuple_*" back out into the component field
names in __getattr__ and then calls _make_named_tuple, rather than
relying solely on a factory function as I have done here.
However, it also isn't all that hard to imagine a literal syntax
instead using a dedicated builtin type factory (perhaps based on
structseq) that implicitly produced types that knew to rely on the
appropriate builtin to handle instance creation on unpickling - the
hardest part of the problem (preserving the keyword argument order)
was already addressed in 3.6.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list