为什么使用`namedtuple` + `namedtuple`返回的是普通元组?

huangapple go评论70阅读模式
英文:

Why does namedtuple + namedtuple return a regular tuple?

问题

from collections import namedtuple

foo_a = namedtuple("foo_a", ["a1", "a2", "a3"])
foo_b = namedtuple("foo_b", ["b1", "b2", "b3"])

a = foo_a(1, 2, 3)
b = foo_b(4, 5, 6)

a + b        # -> (1, 2, 3, 4, 5, 6)
type(a + b)  # -> tuple

看起来,namedtuple 的 add 方法会返回一个元组,但我找不到关于这种行为的文档。这种行为对我来说似乎很奇怪。

英文:
from collections import namedtuple

foo_a = namedtuple("foo_a", ["a1", "a2", "a3"])
foo_b = namedtuple("foo_b", ["b1", "b2", "b3"])

a = foo_a(1, 2, 3)
b = foo_b(4, 5, 6)

a + b        # -> (1, 2, 3, 4, 5, 6)
type(a + b)  # -> tuple

It seems that the add method of namedtuples will return a tuple, but I cannot find the documentation for this behavior. And this behavior seems strange to me.

答案1

得分: 3

Python的命名元组(namedtuples)被精心构建,使得它们是元组的子类 - 这意味着它们在每一个可能的机会上都会像元组一样表现。当然,最常用的是通过数字索引而不是通过命名属性来获取其值的能力:这就是使它们能够在以前需要元组来将不相关的值绑定在一起的地方成为“插入式”替代品的原因。

使用“+”来连接元组,或者将元组连接到其他可迭代对象是定义良好的。另一方面,连接命名元组的命名属性不仅没有意义,而且如果结果实体是一个“双长度命名元组”,每个字段都重复两次,将会导致名称冲突。

改变行为以递归地添加每个字段,除了对大多数命名元组来说可能没有意义之外,还会破坏命名元组到元组的兼容性。如果尝试将命名元组添加到任何其他序列时只是简单地引发TypeError,那么预期的结果对象也是一个元组,因为命名元组本质上就是一个元组。

当考虑到这些要点时,我认为这种行为实际上并没有什么令人惊讶的地方。

英文:

Python's namedtuples are carefully built so that they are subclasses of tuples - this means that they will behave just as tuples will in every possible opportunity. The most used of course, is the capability of getting its values by a numeric index rather than by named attribute: this is what makes them capable of being "drop in" replacements in places where formerly a tuple was needed just to tie unrelated values together.

The use of "+" to concatenate tuples, or a tuple to other iterable is well defined. On the other hand, concatenating the named attributes of a namedtuple not only does not make sense, as it would cause a name clash if the resulting entity would be a "double-length named tuple" with each field repeated twice.

Changing the behavior to add each field recursively, besides not necessarily making sense for most named tuples, would also break compatibility of named-tuples to tuples. As would simply raising a TypeError when trying to add a namedtuple to any other sequence: as a namedtuple is a tuple, the expected resulting object is also a tuple.

I don't think there is actually any surprise in this behavior when one takes these points into consideration.

huangapple
  • 本文由 发表于 2023年8月9日 06:58:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定