namedtuple._replace() 不像文档中描述的那样工作

Posted

技术标签:

【中文标题】namedtuple._replace() 不像文档中描述的那样工作【英文标题】:namedtuple._replace() doesn't work as described in the documentation 【发布时间】:2011-01-11 02:09:18 【问题描述】:

我在实现namedtuple._replace() 时遇到了问题,所以我直接从文档中复制了代码:

Point = namedtuple('Point', 'x,y')

p = Point(x=11, y=22)

p._replace(x=33)

print p

我得到了:

Point(x=11, y=22)

代替:

Point(x=33, y=22)

如文档中所示。

我在 Windows 7 上使用 Python 2.6

发生了什么事?

【问题讨论】:

这与 str.replace() 的工作方式相同。字符串和命名元组都是不可变的,因此它们的替换方法会产生 new 值,同时保持旧值不变。您的问题的解决方案是将新结果保存到变量中。 很好的问题,如果没有其他原因,每个想要“修改”命名元组的人都会在某个时候绊倒。 【参考方案1】:

是的,它的工作原理与文档完全一致。

._replace返回一个新的namedtuple,它不会修改原来的,所以你需要这样写:

p = p._replace(x=33)

请参阅此处:somenamedtuple._replace(kwargs) 了解更多信息。

【讨论】:

从文档中需要注意的一点是:我对使用下划线前缀的方法持谨慎态度,因为这通常用于指示 the method is private。但是在这种情况下,这样做是为了避免与namedtuple 的字段(可能包括称为replace 的内容)发生冲突,因此可以安全使用。有一个 ._asdict() 方法,其工作方式类似。【参考方案2】:

元组是不可变的。 _replace() 返回一个包含您修改的新元组:

p = p._replace(x=33)

【讨论】:

【参考方案3】:

namedtuple._replace() 返回一个新元组;原件不变。

【讨论】:

【参考方案4】:

在我看来,namedtuple 就像它的前身元组一样是不可变的。

>>> from collections import namedtuple
>>> Point = namedtuple('Point', 'x,y')
>>>
>>> p = Point(x=11, y=22)
>>>
>>> p._replace(x=33)
Point(x=33, y=22)
>>> print(p)
Point(x=11, y=22)
>>> p = p._replace(x=33)
>>> print(p)
Point(x=33, y=22)

NamedTuple._replace 返回一个新的 NamedTuple 类型相同但值已更改。

【讨论】:

FWIW,方法名称的灵感来自 str.replace(),它的使用模式非常相似 :-) s='the quick brown fox'; s=s.replace('quick', 'slow') 雷蒙德·赫廷格?很荣幸。【参考方案5】:

但是是的,你是对的:在“官方”文档中,他们忘记将替换的元组分配给一个变量:https://docs.python.org/3/library/collections.html?highlight=collections#collections.namedtuple

p._replace(x=33)

而不是

p1 = p._replace(x33)

【讨论】:

官方文档显示,当您在交互式 Python 提示符下运行 p._replace(x=33) 时,它会将新元组输出到屏幕。他们没有忘记任何东西,这是非常好的交互式使用。下一行显示了一段更复杂的代码,其中返回值被分配给某物。

以上是关于namedtuple._replace() 不像文档中描述的那样工作的主要内容,如果未能解决你的问题,请参考以下文章

Python数据结构与算法---namedtuple

为啥 Python 不支持记录类型? (即可变的命名元组)

Python namedtuple 的可变默认参数

namedtuple 的等式重载

div 可像文本区域一样调整大小

让 namedtuple 接受 kwargs