Different behaviour for list.__iadd__ and list.__add__
请考虑以下代码:
1 2 3 4 5 6
| >>> x = y = [1, 2, 3, 4]
>>> x += [4]
>>> x
[1, 2, 3, 4, 4]
>>> y
[1, 2, 3, 4, 4] |
然后考虑一下:
1 2 3 4 5 6
| >>> x = y = [1, 2, 3, 4]
>>> x = x + [4]
>>> x
[1, 2, 3, 4, 4]
>>> y
[1, 2, 3, 4] |
为什么这两者有区别?
(是的,我试着找这个)。
- 最后一句话有趣的是,这个功能实际上是在python文档中解释的:docs.python.org/reference/datamodel.html object. add_uuuu(从搜索这些术语开始)
- @JDL:是的,我承认我忽略了这一点。
__iadd__使列表发生变异,而__add__返回一个新的列表,如图所示。
x += y的一个表达式首先试图调用__iadd__,如果没有调用__add__,则调用__add__,然后执行了一个分配(请参阅sven的评论以获得一个小的更正)。既然list有__iadd__,那么它就有了这个小小的"o"突变魔法。
- 如果您想了解更多关于这种精确行为的细节以及其他关于为什么Python是这样的见解,我强烈推荐Pycon2012的Python顿悟演讲。它会让你得到很多"哈哈!"时刻。
- @S singh如果您得到了答案,请选择该答案作为接受的答案,并完成工作流程。否则,此问题将显示为未回答。
- 这个回答有点误导性:无论调用__iadd__()还是__add__(),都始终执行分配。但是,list.__iadd__()只返回self,因此除了将目标名称呈现为当前作用域的本地名称外,该分配没有任何效果。
- 另外:__iadd__对list的工作速度更快(它改变对象的位置,而不是重新创建一个);它允许附加任何一个iterable;a = []a+=range(5)对list的工作;a = a + smth要求smth作为list的实例。
第一个改变列表,第二个重新绑定名称。