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 -= ba = 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中的两个赋值运算符有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的一个等号和两个等号有啥区别

C++中赋值运算操作符和=重载有啥区别?

Delphi中赋值(:=)与分配(Assign)有啥区别?

python中的构造函数和初始化程序有啥区别? [复制]

: 和 ?? 之间有啥区别? PHP 运算符? [复制]

Bash 中的 [ 和 [[ 有啥区别? [复制]