python 中的 namedtuple 语法与内置类型和 orderedDict 很奇怪

namedtuple in python syntax weird from built-in types and orderedDict

这是我关于 Whosebug 的第一个问题。我刚刚学习了 namedtuple 并发现了一些奇怪的东西。

当你想从一个可迭代对象中启动一个命名元组时,你必须添加前缀 * 或使用 _make 方法。

例如:

City=namedtuple('city',['name','country','population','coordinates'])

delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))

delhi = City(*('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889)))

但是当你从同一个集合包中启动元组、字典甚至 orderedDict 时,你可以只使用 tuple() 或 dict() 或 orderedDict()。

例如:

from collections import OrderedDict

items = (
('A', 1),
('B', 2),
('C', 3)
)

regular_dict = dict(items)

ordered_dict = OrderedDict(items)

为什么 namedtuple 的语法如此奇怪?谢谢!

从你的例子来看,它的行为类似于字典:

from collections import namedtuple
MyTuple = namedtuple('MyTuple', 'A B C')

items = (('A', 1), ('B', 2), ('C', 3))

my_tuple = MyTuple(**dict(items))

您可以看到一些讨论 here 为什么 namedtuple 是这样设计的。基本原因是 "normal" 创建 namedtuple 的方法是使用像 MyTupleClass(1, 2, 3) 这样的调用,其中值被接受为单独的参数。如果它只接受一个可迭代参数(如 tuple 所做的那样),您将 必须 编写带有一组额外括号的 MyTupleClass((1, 2, 3)) (即 MyTupleClass(1, 2, 3) 会引发错误,就像 tuple(1, 2, 3) 那样)。确实,这意味着如果从可迭代对象初始化,您必须使用额外的星号(或使用 ._make() 方法),但这并不难,只是不同而已。这个决定显然是为了使简单的情况(用文字值初始化)更容易,但代价是使更复杂的情况(从可迭代中解包)与常规元组有点不同。