Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the first argument of namedtuple used for?

Tags:

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.

like image 471
WKPlus Avatar asked May 29 '15 09:05

WKPlus


People also ask

What is NamedTuple used for?

Python's namedtuple() is a factory function available in collections . It allows you to create tuple subclasses with named fields. You can access the values in a given named tuple using the dot notation and the field names, like in obj.

What's the advantage of using NamedTuple instead of tuple?

This is because tuples are immutable. However, using a tuple may reduce the readability of your code as you cannot describe what each item in the tuple stands for. This is where NamedTuples can come in handy. A NamedTuple provides the immutability of a tuple, while also making your code easy to understand and use.

What does NamedTuple on a collection type return?

NamedTuple can return the values with keys as OrderedDict type object. To make it OrderedDict, we have to use the _asdict() method.

What is an advantage of NamedTuples over dictionaries?

Moreover, as namedtuple instances do not have per-instance dictionaries, they are lightweight and require no more memory than regular tuples. This makes them faster than dictionaries.


1 Answers

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.

like image 86
Martijn Pieters Avatar answered Oct 22 '22 02:10

Martijn Pieters