[Python-ideas] Anonymous namedtuples

Joseph Martinot-Lagarde contrebasse at gmail.com
Tue Apr 19 09:48:08 EDT 2016


Steven D'Aprano <steve at ...> writes:

> py> from collections import namedtuple
> py> my_tuple = namedtuple("_", "x y z")(1, 2, 3)
> py> print(my_tuple)
> _(x=1, y=2, z=3)

This looks nice with a short number of short attribute names, but in a real
case separating the values from their corresponding field hurts readability.
Compare:

    my_tuple = namedtuple("_", "site, gisement, range_nominal, range_bista,
is_monostatic")(12.45, 45.0, 3000.0, 2998.5357, True)
    my_tuple = (site=12.45, gisement=45.0, range_nominal=3000.0,
range_bista=2998.5357, is_monostatic=True)

As a side note, if the empty string would be allowed for the class name the
printed value would look better. The fact that it's not possible right now
looks liek an implementation "detail".

> > Another hting I don't like about namedtuples is the duplication of the name.
> > TYpical declarations look like `Point = namedtuple('Point', ['x', 'y'])`,
> > where `Point` is repeated two times. I'll go one step further and say that
> > the name is useless most of the time, so let's just get rid of it.
> 
> The name is not useless. It is very useful for string representations, 
> debugging, introspection, and generally having a clue what the object 
> represents. How else do you know what kind of object you are dealing 
> with?
>
> In my opinion, avoiding having to repeat the name twice is a "nice to 
> have", not a "must have".

Of course he name is not completely useless, but you can often know what a
namedtuple represents in your application or your script from the field
names only (or the variable name). SimpleNamespace live very well without a
name, for example.

> >     my_point = (x=12, y=16)
> >     # (x=12, y=16)
> >     my_point[0]
> >     # 12
> 
> How do you know that the 0th item is field "x"?
> 
> Keyword arguments are not ordered.

In my proposal these are not keywords arguments, they are a syntax construct
to build a anonymous namedtuple. That's why I can't just create a factory
function.
The order is determiend by the construction, and can be found by
introspection (simply printing the object will do).

I suppose that as a developper it's a shift from how keywords behave now,
but as a user a namedtuple is still a tuple, and it keeps the ordering.

> Consider that since they're tuples, we should be able to provide the 
> items as positional arguments to the construct, just like regular 
> namedtuples:
> 
> pt = (x=12, y=16)
> type(pt)(1, 2)

They inherits tuples, that doesn't mean that they behave in all cases like
tuples. In that case I guess that this form would not be allowed. I don't
know how bad this looks for a python dev though!

> Obviously we don't want every instance to belong to a distinct class, so 
> we need some sort of cache. SimpleNamespace solves this problem by 
> making all instances belong to the same class. That's another difference 
> between namedtuple and what you seem to want.

Yes, that's another difference, I don't want to replicate namedtuples
exactly (otherwise I'd just use a namedtuple). I don't think that you need a
cache, more like a frozendict per instance which binds the fields to the
corresponding index. Maybe it's what you call cache ?


>From your comments I get that a problem is that the only way to create an
anonymous namedtuple would be via the syntax construct, it's not possible to
use the class constructor directly. I would argue that it's not a problem
becaus if you need to do that you can just use a standard namedtuple, that's
exactly what it's here for. Anonymous namedtuple are for quick, easy, and
readable use.
Maybe that means that the added syntax complexity is not worth it.



More information about the Python-ideas mailing list