python中的两个赋值运算符有啥区别? [复制]
Posted
技术标签:
【中文标题】python中的两个赋值运算符有啥区别? [复制]【英文标题】:what is the difference between two assignment operator in python? [duplicate]python中的两个赋值运算符有什么区别? [复制] 【发布时间】:2013-11-26 12:17:32 【问题描述】:In [38]: d = set(range(3))
In [39]: d
Out[39]: set([0, 1, 2])
In [40]: for i in d:
d -= set([2])
....:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
/home/gridlex/workspace/HomeBackSites/nava_scripts/<ipython-input-40-b79926ab34ec> in <module>()
----> 1 for i in d:
2 d -= set([2])
3
RuntimeError: Set changed size during iteration
这两个在 python 中的赋值有什么区别?
1.d -= set([2])
2 d = d - set([2])
In [41]: d = set(range(3))
In [42]: for i in d:
d = d - set([2])
....:
In [43]: d
Out[43]: set([0, 1])
【问题讨论】:
该死的搜索和运营商。这肯定是重复的。 在想同样的事情。 搜索__iadd__
、__isub__
等应该更容易。但我发现的第一件事,here,是关于如何实现 +=,而不是它的作用,并且它接受的答案具有误导性。
【参考方案1】:
对于整数等不可变类型,a -= b
与 a = a - b
相同:它创建一个新值 a - b
,并重新绑定名称 a
以引用该新值而不是旧值一个。
但是对于像集合这样的可变类型,a -= b
会更改 a
原地指向的值。 (它还将a
重新绑定到它已经引用的相同值,但这并不重要。)
查看这一点的最佳方法是查看对象的身份:
>>> s1 = set(range(3))
>>> s2 = s1
>>> s1, id(s1), s2, id(s2)
(0, 1, 2, 4303749432, 0, 1, 2, 4303749432)
>>> s1 -= 1
>>> s1, id(s1), s2, id(s2)
(0, 2, 4303749432, 0, 2, 4303749432)
>>> s1 = s1 - 2
>>> s1, id(s1), s2, id(s2)
(0, 4303749664, 0, 2, 4303749432)
注意-=
离开s1
仍然指代与s2
相同的集合,并更改该集合; -
离开 s1
指的是具有不同 id
的全新集合,并且不影响 s2
。
在幕后,a = a - b
大致* 相当于 a = a.__sub__(b)
,而 a -= b
相当于 a = a.__isub__(b)
。除了如果没有__isub__
方法,a -= b
只是使用__sub__
代替。
__isub__
更改值,而 __sub__
返回一个新值这一事实并没有真正由语言强制执行,但对于所有内置类型和 stdlib 类型来说都是如此,并且应该是这样的任何自定义类型。它在文档中的Emulating numeric types 中进行了描述:
这些 [
__ifoo__
] 方法应该尝试就地执行操作(修改 self)并返回结果(可以是,但不一定是,self )。如果未定义特定方法,则扩充分配回退到正常方法。例如,要执行语句x += y
,其中x 是具有__iadd__()
方法的类的实例,调用x.__iadd__(y)
。如果 x 是未定义__iadd__()
方法的类的实例,则考虑x.__add__(y)
和y.__radd__(x)
,与评估x + y
一样。
* 它不是完全等效的,因为 (a) __rsub__
,(b) 在 C 中实现的类型(如 set
),以及 (c) 查找某些特殊方法的规则是不同于一般的方法。
【讨论】:
以上是关于python中的两个赋值运算符有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章