WKPlus
WKPlus

Reputation: 7255

What's the first argument of namedtuple used for?

We use namedtuple like this:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p=Point(1,2)
>>> p.x
1

I found the first argument of namedtuple seems useless, since:

Firstly, we can not use it (to create an instance, for example):

>>> from collections import namedtuple
>>> P = namedtuple('Point', ['x', 'y'])
>>> p = Point(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Point' is not defined

Secondly, there seems no constraint for it (for example, we don't have to make it unique):

>>> P1 = namedtuple('Point', ['x', 'y'])
>>> P2 = namedtuple('Point', ['x', 'y', 'z'])
>>> p1 = P1(1,2)
>>> p2 = P2(1,2,3)
>>> p1
Point(x=1, y=2)
>>> p2
Point(x=1, y=2, z=3)

I did not find a explanation from the manual or by googling. There is a relevant question here, but it did not answer why namedtuple need the first argument and how it can be used or when it's necessary.

Upvotes: 22

Views: 2337

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124248

It sets the name of the generated class:

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> Point
<class '__main__.Point'>
>>> Point = namedtuple('Foobar', ['x', 'y'])
>>> Point
<class '__main__.Foobar'>

The Point name in your globals is just a reference to the generated class, the class itself needs to have a name. The name cannot be taken from the variable to which the object is assigned, because the class is generated first and only then assigned in a separate step (after the namedtuple() call returns).

It doesn't need to be unique in the same way that a class name doesn't need to be unique when using class:

>>> class Foo(object):
...     pass
... 
>>> Bar = Foo
>>> class Foo(object):
...     pass
... 
>>> Bar
<class '__main__.Foo'>
>>> Foo
<class '__main__.Foo'>

You usually avoid that kind of thing by keeping names unique per module, but you don't have to.

The name is there for debugging purposes; in tracebacks and in repr() output the name is shown to help you figure out what class is used.

To Python, it doesn't matter if the generated class reuses a name. It does to the pickle module; if you need to be able to pickle your named tuple class instances, make sure you pick a name that matches the global by which pickle can later load it again. But if re-using a name makes sense to you or doesn't actively hinder your code development or debugging tasks, then by all means, reuse the name or pick anything you like.

Upvotes: 20

Related Questions