Python 中“i += x”何时与“i = i + x”不同?
- 2024-12-06 08:39:00
- admin 原创
- 94
问题描述:
有人告诉我+=
会产生与 标准符号 不同的效果。 是否存在与 不同i = i +
的情况?i += 1
`i = i + 1`
解决方案 1:
这完全取决于对象i
。
+=
调用__iadd__
方法__add__
(如果存在,如果不存在则返回),而+
调用__add__
方法1或__radd__
在少数情况下调用方法2。
从 API 的角度来看,__iadd__
应该用于就地修改可变对象(返回已变异的对象),而__add__
应该返回某个对象的新实例。对于不可变对象,这两种方法都返回一个新实例,但__iadd__
会将新实例放在当前命名空间中,并使用与旧实例相同的名称。这就是为什么
i = 1
i += 1
似乎增加了i
。实际上,您获得一个新的整数并将其“赋值于” i
—— 丢失了对旧整数的一个引用。在这种情况下,i += 1
与 完全相同i = i + 1
。但是,对于大多数可变对象,情况就不同了:
举一个具体的例子:
a = [1, 2, 3]
b = a
b += [1, 2, 3]
print(a) # [1, 2, 3, 1, 2, 3]
print(b) # [1, 2, 3, 1, 2, 3]
相比:
a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print(a) # [1, 2, 3]
print(b) # [1, 2, 3, 1, 2, 3]
注意在第一个例子中,由于b
和a
引用同一个对象,当我使用+=
on时b
,它实际上会发生变化b
(并且a
也会看到变化——毕竟,它引用的是同一个列表)。然而在第二个例子中,当我使用 do 时b = b + [1, 2, 3]
,它会获取引用的列表b
并将其与新列表连接起来[1, 2, 3]
。然后它将连接的列表存储在当前命名空间中b
——而不考虑b
之前的行是什么。
1在表达式中x + y
,如果x.__add__
未实现或x.__add__(y)
返回NotImplemented
和 x
和y
具有不同类型的,则x + y
尝试调用y.__radd__(x)
。因此,在以下情况下
foo_instance += bar_instance
如果Foo
没有实现__add__
,__iadd__
那么这里的结果与
foo_instance = bar_instance.__radd__(bar_instance, foo_instance)
2在表达式 中foo_instance + bar_instance
,如果的类型是 类型的子类(例如),bar_instance.__radd__
则将先尝试。这样做的理由是在某种程度上是比 更“高级”的对象,因此应该获得覆盖 行为的选项。foo_instance.__add__
bar_instance
`foo_instanceissubclass(Bar, Foo)
BarFoo
Bar`Foo
解决方案 2:
在幕后,i += 1
做了类似这样的事情:
try:
i = i.__iadd__(1)
except AttributeError:
i = i.__add__(1)
虽然i = i + 1
做了这样的事情:
i = i.__add__(1)
这稍微有点过于简单了,但你可以明白我的意思:Python+=
通过创建__iadd__
方法以及,为类型提供了一种特殊处理的方法__add__
。
目的是可变类型(例如list
)将在中自我变异__iadd__
(然后返回self
,除非您正在做一些非常棘手的事情),而不可变类型(例如int
)将不会实现它。
例如:
>>> l1 = []
>>> l2 = l1
>>> l1 += [3]
>>> l2
[3]
因为l2
与是同一个对象l1
,并且你变异了l1
,所以你也变异了l2
。
但:
>>> l1 = []
>>> l2 = l1
>>> l1 = l1 + [3]
>>> l2
[]
在这里,您并没有改变l1
;相反,您创建了一个新列表,l1 + [3]
并重新绑定名称l1
以指向它,同时仍l2
指向原始列表。
(在+=
版本中,您也重新绑定了l1
,只是在那种情况下您将其重新绑定到list
已经绑定到的相同内容,因此您通常可以忽略该部分。)
解决方案 3:
i += x
这是一个直接与之比较的例子i = i + x
:
def foo(x):
x = x + [42]
def bar(x):
x += [42]
c = [27]
foo(c); # c is not changed
bar(c); # c is changed to [27, 42]
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件