8

While reading fmark's answer to the question What are "named tuples" in Python? I saw that the example given there had the same name and reference, i.e. the word Point appears twice in the following statement:

Point = namedtuple('Point', 'x y')

So I went to the original reference:
https://docs.python.org/2/library/collections.html#collections.namedtuple
And here too I found two more examples:

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
Color = namedtuple('Color', 'red green blue')

Ideally words are not repeated in Python. For instance the whole line (for the the Point example) could be replaced by the following:

namedtuple('Point', 'x y')

OR

Point = namedtuple('x y')

Of course, that's assuming that the named tuple has to have the same name and reference. So my question is: when is it advisable (if at all it is permitted) that a named tuple should have a different name and reference? I am yet to come across an example.

JohnE
  • 29,156
  • 8
  • 79
  • 109
Shashank Sawant
  • 1,111
  • 5
  • 22
  • 40
  • 1
    `namedtuple('Point'...)` creates a class called 'Point', however without assigning it to some identifier you can only use it once, e.g. `point1 = namedtuple('Point', 'x y')(1, 0)`, and `type(point1) is `. It is convenient to use an identifier that matches the class name, but it is not required, e.g. `Vertex = namedtuple('Point'...)`. A class is just another object in python and you would use a different name any time you would assign a different identifier to a class name, e.g. `class Point: ... Vertex = Point` – AChampion Mar 31 '15 at 02:04
  • 2
    In my opinion, the `namedtuple` module is a horrible mess and should have been written using metaclasses in the first place. It is still not at all clear to me [why it wasn't](http://stackoverflow.com/questions/28184531), but if it had been, you would have the option of using class definitions for you named tuples, designating a metaclass, not needing to repeat the class name. – Rick Mar 31 '15 at 03:41

1 Answers1

13

You can do it, it will just annoy you.

In [1]: import collections

In [2]: Point = collections.namedtuple('Rectangle', 'x y')

In [3]: Point(1, 2)
Out[3]: Rectangle(x=1, y=2)

This is confusing, don't do it unless you have a very good reason.

The reason why this happens is because namedtuple() is just a function, it has no special knowledge about how it is being used as a declaration. In languages with macros, namedtuple() would be a macro which expands to a declaration instead. So, rather than tack on a macro system or walk the call stack for the name, you have to specify name twice.

So it is one of Python's "warts", or a design compromise, depending on how you feel about it.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • 1
    More particularly: the reason it happens is `namedtuple` was written using `exec` and string formatting instead of using metaclasses (which have the first `name` argument bound to the supplied metaclass instance name). Why is this? [Who knows.](http://stackoverflow.com/questions/28184531/why-doesnt-the-namedtuple-module-use-a-metaclass-to-create-nt-class-objects) – Rick Mar 31 '15 at 03:37
  • Though to be fair, you do still have to repeat the classname when using a metaclass as a class factory (e.g. `type('name', (object,),{})`). – Rick Mar 31 '15 at 03:44