[Python-ideas] namedtuple literals [Was: RE a new namedtuple]
Terry Reedy
tjreedy at udel.edu
Sun Jul 30 21:40:19 EDT 2017
On 7/30/2017 2:57 PM, Markus Meskanen wrote:
> I've been experimenting with this:
>
> class QuickNamedTuple(tuple):
>
> def __new__(cls, **kwargs):
> inst = super().__new__(cls, tuple(kwargs.values()))
> inst._names = tuple(kwargs.keys())
> return inst
>
> def __getattr__(self, attr):
> if attr in self._names:
> return self[self._names.index(attr)]
> raise AttributeError(attr)
>
> def __repr__(self):
> values = []
> for i, name in enumerate(self._names):
> values.append(f'{name}={self[i]}')
> return f'({", ".join(values)})'
>
> It's a quick scrap and probably not ideal code, but the idea is the
> point. I believe this is how the new "quick" named tuple should ideally
> work:
>
> In: ntuple = QuickNamedTuple(x=1, y=2, z=-1)
> In: ntuple
> Out: (x=1, y=2, z=-1)
> In: ntuple[1] == ntuple.y
> Out: True
> In: ntuple == (1, 2, 3)
> Out: True
> In: ntuple == QuickNamedTuple(z=-1, y=2, x=1)
> Out: False
>
> So yeah, the order of the keyword arguments would matter in my case, and
> I've found it to work the best. How often do you get the keywords in a
> random order? And for those cases, you have SimpleNameSpace, or you can
> just use the old namedtuple. But most of the time you always have the
> same attributes in the same order (think of reading a CSV for example),
> and this would be just a normal tuple, but with custom names for the
> indexes.
Using a name to position map:
class QuickNamedTuple(tuple):
def __new__(cls, **kwargs):
inst = super().__new__(cls, tuple(kwargs.values()))
inst._namepos = {name: i for i, name in enumerate(kwargs.keys())}
return inst
def __getattr__(self, attr):
try:
return self[self._namepos[attr]]
except KeyError:
raise AttributeError(attr) from None
def __repr__(self):
values = []
for name, i in self._namepos.items():
values.append(f'{name}={self[i]}')
return f'({", ".join(values)})'
Same outputs as above.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list