[Python-ideas] A namedtuple literal.

Yury Selivanov yselivanov.ml at gmail.com
Wed Apr 2 23:51:50 CEST 2014


On 2014-04-02, 5:27 PM, Steven D'Aprano wrote:
> On Wed, Apr 02, 2014 at 06:34:00PM +0200, Philipp A. wrote:
>> 2014-04-02 17:20 GMT+02:00 Yury Selivanov <yselivanov.ml at gmail.com>:
>>
>>> But when you have a key name defined in a variable, you’ll need to do
>>>
>>> key = 'spam'
>>> o = {}
>>> o[key] = 'ham'
>>>
>>> Where in Python, you’d simply write {key: ‘ham’}.
>>>
>>> So for Python, I think that having unquoted keys in literals is a
>>> bad idea.
>> i totally agree for dicts, but here i don’t. instead i’d require unquoted
>> keys like in kwargs.
> These would be reasonable points to consider if the idea of literal
> namedtuple syntax was a serious idea to consider, but I don't think it
> is. Please look again at Eric's original post, and take note of the last
> thing he says, and remember that there is a tradition in Anglo-American
> culture of making "April Fools" jokes and other non-serious suggestions.

Well, even if it was intended as an April Fools joke, I still
like the idea :)

> namedtuple, as it exists, creates a class, which you then instantiate.
> It's a factory function, not a class itself:
>
> py> from collections import namedtuple
> py> type(namedtuple)
> <class 'function'>
Do you want dict literal to create a new class for each
key combination?

> But Eric's suggestion skips creating a distinct class and gives you an
> instance straight away. So what class will the instance belong to? There
> are three obvious possibilities, and they're all unfortunate:
>
>
> (1) every instance is a singleton of a unique class;
>
> (2) there is a single NamedTuple class that every instance belongs to;
I think it's going to be (2). Like what we currently
have for regular 'tuple'.

> (3) the namedtuple literal has to cache the keys it has seen, and return
> the same class when given the same keys in the same order.
>
>
> None of them are ideal; #3 means that if module a creates a namedtuple,
> and module b creates a namedtuple that just happens to use the same
> field names, they will have the same type. Most of the time that will
> not matter, but occasionally it will lead to problems.

I was told on this list once: namedtuple is a protocol. We don't
need a common base class for them, we don't really need isinstance
to work on them.

> (e.g. suppose module a enforces some constraint on the field values, but
> module b does not. Then if a namedtuple from b somehow gets passed to
> module a, which does an isinstance type check to validate the
> namedtuple, the constraint will be broken).
>
> #2 on the other hand means that:
>
>      vector = (x: 2.3, y: -4.2, z: 1.7)
>      colour = (red: 100, green: 5, blue: 203)
>
> will be considered the same type. For something meant to be considered
> as a record or struct, I think that's a bad idea.

Same as (1, 2) is the same type as ('1', '2', '3').

> #1 on the other hand means that:
>
>      p = (x: 2, y: 3)
>      q = (x: 2, y: 3)
>
> will be considered different types, which is surely going to come to a
> big surprise to most people.

But p will be equal to q. That's all that matters.
Again, same for

    p = (2, 3)
    q = (2, 3)

I think that if we indeed treat namedtuples as more
convenient version of regular tuples, then Eric's proposal
makes a lot of sense.

Yury


More information about the Python-ideas mailing list