namedtuple._replace()在文档中描述的方式无法正常工作。

63

我在实现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。

发生了什么事情?


8
这个功能和str.replace()的使用方式相同。由于字符串和命名元组都是不可变类型,因此它们的替换方法会生成新的值,同时保留旧的值不变。解决您的问题的方法是将新结果保存到一个变量中。 - Raymond Hettinger
这是一个非常好的问题,因为每个想要“修改”namedtuple的人在某个时候都会遇到这个问题。 - mbarkhau
5个回答

123

是的,它确实如文档所述正常工作。

._replace 返回一个新的namedtuple,它不会修改原始对象,因此你需要编写以下代码:

p = p._replace(x=33)

请查看此处:somenamedtuple._replace(kwargs) 以获取更多信息。


6
从文档中需要注意的一点是:我一开始有所疑虑,不确定是否应该使用下划线前缀方法,因为通常这么做是为了表示该方法是私有的。但是,在这种情况下,这样做是为了避免与namedtuple的字段发生冲突(其中可能包括名为replace的内容),因此可以放心使用。还有一个类似的._asdict()方法。 - Chris Vandevelde

21

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

p = p._replace(x=33)

12

6

在我看来,namedtuple 就像其前辈 tuple 一样是不可变的。

>>> 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)
< p > NamedTuple._replace 返回一个新的NamedTuple,与原来的类型相同,但值已更改。


5
顺便说一句,这个方法的名称是受到了str.replace()的启发,两者使用方式非常相似 :-) s='the quick brown fox'; s=s.replace('quick', 'slow') - Raymond Hettinger
3
那位 Raymond Hettinger?荣幸。 - hughdbrown

1

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接