20

我们namedtuple这样使用:

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

我发现 的第一个论点namedtuple似乎没用,因为:

首先,我们不能使用它(例如创建实例):

>>> 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

其次,它似乎没有限制(例如,我们不必使其唯一):

>>> 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)

我没有从手册或谷歌搜索中找到解释。这里有一个相关的问题,但它没有回答为什么namedtuple需要第一个参数以及如何使用它或何时需要。

4

1 回答 1

20

它设置生成的类的名称:

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

全局变量中的Point名称只是对生成的类的引用,类本身需要有一个名称。不能从分配对象的变量中获取名称,因为首先生成类,然后才在单独的步骤中分配(在namedtuple()调用返回之后)。

它不需要是唯一的,就像使用时类名不需要唯一一样class

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

您通常通过保持每个模块的名称唯一来避免这种事情,但您不必这样

该名称用于调试目的;在回溯和repr()输出中显示名称以帮助您确定使用的类。

对于 Python,生成的类是否重用名称并不重要。它对pickle模块起作用;如果您需要能够腌制您的命名元组类实例,请确保选择与全局匹配的名称,以便pickle稍后再次加载它。但是,如果重用名称对您有意义或不会积极阻碍您的代码开发或调试任务,那么请务必重用名称或选择任何您喜欢的名称。

于 2015-05-29T09:37:08.313 回答