为什么在Python中创建namedtuple时必须提供typename作为第一个参数

idW*_*ter 3 python python-2.7

在 collections.namedtuple() 构造函数中,第一个参数是您要创建的类型的名称,但据我所知,它与诊断消息无关。

from collections import namedtuple
Point = namedtuple('Point', 'x y')
p = Point(1,2)   # works fine, creates Point(x=1, y=2)

Point = namedtuple('blah', 'x y')
p = Point(2,3)   # works fine, creates blah(x=1,y=2)
Run Code Online (Sandbox Code Playgroud)

这是否只是程序员应该为诊断目的保持一致的必要项目,因为 Python 无法了解您将命名元组分配给的变量的名称?似乎容易出错,但我可以看出这是多么必要。只是想知道这两个名称不匹配是否还有其他原因或影响。

pok*_*oke 5

命名元组以一种肮脏的方式实现。有一个模板字符串有几个占位符,当你调用namedtuple()时,实际发生的事情是这些占位符被参数替换,模板被eval'd。这个实现看起来很脏(因为它使用了 eval),但确实简单而强大。

缺点是实际上需要一个类名,因为第一行之一实际上是这样的:class {typename}(tuple):。因此,您确实需要指定一个类型名称才能使其工作。

至于该名称的值,这并不重要,但正如您自己所说,出于调试目的,选择您也用于保存类型的变量的相同名称很有用。否则,整个事情不会有太大的不同:

class CustomType:
    …

# assign a new name, and never talk about CustomType again
NewName = CustomType
Run Code Online (Sandbox Code Playgroud)

  • “永远不要再谈论 CustomType”。或者,就此而言,`del CustomType`。很容易忘记 Python 中的 `def` 和 `class` 不会在它们创建的对象的名称(即函数或类)和它们分配给它的属性/变量的名称之间建立任何内在的联系。它们对两者使用相同的名称,`collections.namedtuple` 不能这样做,因为它只是一个函数调用而不是内置语言,所以它不能“看到”赋值。事实上,可能没有赋值,你可以只写`namedtuple('Foo', 'x')(1)` (2认同)