[Python-ideas] A namedtuple literal.

Andrew Barnert abarnert at yahoo.com
Wed Apr 2 23:59:23 CEST 2014


On Apr 2, 2014, at 14:27, Steven D'Aprano <steve at pearwood.info> 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>:
>> 
>>> 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.
> 
> 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'>
> 
> 
> 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;
> 
> (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.

You're neglecting the fact namedtuple classes also have to have a "typename" argument. So clearly this syntax would already have to somehow figure out the right typename based on the keys.

Once you solve that simple problem, all matching namedtuple literals in the same namespace are automatically the same type, with no caching needed. (But this also gives you the flexibility to explicitly rebind the name between two literals to create two different types when you need to, without having to reassign colour.__class__, which solves a very common problem.)

And you're also neglecting the fact that we have more than just the keys, we also have the types of the values, and indeed even the values themselves. So, obviously, whenever the compiler sees this:

    colour = (red: 100, green: 5, blue: 203)

... it can tell that you're creating an IntRGB8Color[1], not a FloatRGBColor, or even an IntRGB16Color[2].

So, in conclusion, once you solve the problem of figuring out the intended semantic meaning of the namedtuple literal, everything else is trivial. So dismissing this suggestion as a joke just because it was posted on April Fool's Day seems unfair.

    [1] Of course you wanted it to create an IntRGB8Colour, but you can't expect Python to magically guess whether you want US or UK spellings; that would just be silly.

    [2] In theory these are legal values for an IntRGB16Color, but really, how often do you need literals that are indistinguishable from black but not actually black? I don't think we need to handle that edge case. Perl may have many ways to represent colors that look completely black, but in Python, (0, 0, 0) is the one and only one obvious way to do it.



More information about the Python-ideas mailing list