+= 到底起什么作用?
- 2024-12-27 08:47:00
- admin 原创
- 114
问题描述:
我需要知道+=
Python 中的作用。就这么简单。我还希望能够找到 Python 中其他简写工具定义的链接。
解决方案 1:
在 Python 中,+=
是特殊方法的糖衣__iadd__
,或者__add__
或__radd__
如果__iadd__
不存在。__iadd__
类的方法可以做任何它想做的事情。列表对象实现它并使用它来迭代可迭代对象,将每个元素附加到自身,就像列表的扩展方法一样。
这是一个实现特殊方法的简单自定义类__iadd__
。您使用 int 初始化对象,然后可以使用+=
运算符添加数字。我添加了一个打印语句__iadd__
来显示它被调用。此外,__iadd__
预计会返回一个对象,所以我返回了自身加上另一个数字的加法,这在本例中是有意义的。
>>> class Adder(object):
def __init__(self, num=0):
self.num = num
def __iadd__(self, other):
print 'in __iadd__', other
self.num = self.num + other
return self.num
>>> a = Adder(2)
>>> a += 3
in __iadd__ 3
>>> a
5
解决方案 2:
+=
将变量的值与另一个值相加,然后将新值分配给变量。
>>> x = 3
>>> x += 2
>>> print x
5
-=
,,对于减法,乘法和除法的*=
作用/=
类似。
解决方案 3:
x += 5
`x = x + 5`与在 Python 中说的不完全相同。
请注意:
In [1]: x = [2, 3, 4]
In [2]: y = x
In [3]: x += 7, 8, 9
In [4]: x
Out[4]: [2, 3, 4, 7, 8, 9]
In [5]: y
Out[5]: [2, 3, 4, 7, 8, 9]
In [6]: x += [44, 55]
In [7]: x
Out[7]: [2, 3, 4, 7, 8, 9, 44, 55]
In [8]: y
Out[8]: [2, 3, 4, 7, 8, 9, 44, 55]
In [9]: x = x + [33, 22]
In [10]: x
Out[10]: [2, 3, 4, 7, 8, 9, 44, 55, 33, 22]
In [11]: y
Out[11]: [2, 3, 4, 7, 8, 9, 44, 55]
请参阅:为什么 += 在列表上的行为异常?
解决方案 4:
+=
将数字添加到变量中,从而在过程中更改变量本身(而+
wouldn't 不会)。与此类似,以下代码也会修改变量:
-=
,从变量中减去一个值,并将结果设置为变量*=
,将变量与一个值相乘,使结果成为变量/=
,用变量除以值,使结果成为变量%=
,对变量执行模数运算,然后将变量设置为其结果
可能还有其他。我不是 Python 程序员。
解决方案 5:
这不仅仅是一个语法糖。试试这个:
x = [] # empty list
x += "something" # iterates over the string and appends to list
print(x) # ['s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g']
相对
x = [] # empty list
x = x + "something" # TypeError: can only concatenate list (not "str") to list
操作+=
符调用__iadd__()
列表方法,而+
一个调用__add__()
一个。它们对列表执行的操作不同。
解决方案 6:
它将右操作数添加到左边。 x += 2
意味着x = x + 2
它还可以将元素添加到列表中——请参阅此 SO 线程。
解决方案 7:
理论上,a += b 将 b “添加”到 a 并将结果存储在 a 中。这种简单的描述可以描述许多语言中的 += 运算符。
然而,这种简单的描述引发了几个问题。
我们说的“添加”到底是什么意思呢?
我们所说的“将结果存储在 a 中”到底是什么意思?python 变量不直接存储值,而是存储对对象的引用。
在 python 中,这两个问题的答案都取决于 a 的数据类型。
那么“添加”到底是什么意思呢?
对于数字来说,它意味着数字加法。
对于列表、元组、字符串等来说,它意味着连接。
请注意,对于列表,+= 比 + 更灵活,列表上的 + 运算符需要另一个列表,但 += 运算符将接受任何可迭代的。
那么“将值存储在 a 中”是什么意思呢?
如果对象是可变的,则鼓励(但不要求)就地执行修改。因此 a 指向与之前相同的对象,但该对象现在具有不同的内容。
如果对象是不可变的,那么它显然无法就地执行修改。一些可变对象可能也没有就地“添加”操作的实现。在这种情况下,变量“a”将被更新为指向包含加法运算结果的新对象。
从技术上讲,这是通过首先查找来实现的__IADD__
,如果未实现,则__ADD__
尝试,最后实现__RADD__
。
在 Python 中对变量使用 += 时需要小心,因为我们不确定确切的类型,尤其是我们不确定类型是否可变。例如,考虑以下代码。
def dostuff(a):
b = a
a += (3,4)
print(repr(a)+' '+repr(b))
dostuff((1,2))
dostuff([1,2])
当我们使用元组调用 dostuff 时,元组将作为 += 操作的一部分进行复制,因此 b 不受影响。但是,当我们使用列表调用它时,列表会被就地修改,因此 a 和 b 都会受到影响。
在 python 3 中,观察到“bytes”和“bytearray”类型的类似行为。
最后请注意,即使对象未被替换,也会发生重新分配。如果左侧只是一个变量,这并不重要,但当你有一个引用可变集合的不可变集合时,它可能会导致令人困惑的行为,例如:
a = ([1,2],[3,4])
a[0] += [5]
在这种情况下,[5] 将成功添加到 a[0] 引用的列表中,但是随后当代码尝试重新分配 a[0] 时失败,将引发异常。
解决方案 8:
注意,这与某些情况下包含附加运算符的情况x += y
不同,因为运算符优先级与右侧总是首先被评估的事实相结合,例如x = x + y
>>> x = 2
>>> x += 2 and 1
>>> x
3
>>> x = 2
>>> x = x + 2 and 1
>>> x
1
注意第一个案例扩展为:
>>> x = 2
>>> x = x + (2 and 1)
>>> x
3
你更有可能在“现实世界”中与其他操作员遇到这种情况,例如
x *= 2 + 1
== x = x * (2 + 1)
!=x = x * 2 + 1
解决方案 9:
简短的回答+=
可以翻译为“将 += 右边的内容添加到 += 左边的变量中”。
例如,如果您有,a = 10
那么a += 5
将是: a = a + 5
因此,“a”现在等于 15。
解决方案 10:
根据文档
x += y
相当于x = operator.iadd(x, y)
。另一种说法是,z = operator.iadd(x, y)
相当于复合语句z = x; z += y
。
所以x += 3
和 一样x = x + 3
。
x = 2
x += 3
print(x)
将输出 5。
请注意,还有
&=
//=
<<=
%=
*=
@=
|=
**=
=
-=
/=
^=
解决方案 11:
+=
只是一种写作的捷径
number = 4
number = number + 1
所以你应该写
numbers = 4
numbers += 1
两种方法都是正确的,但示例二可以帮助你少写一点代码
解决方案 12:
我看到很多答案都没有提到使用 += 处理多个整数。
举个例子:
x -= 1 + 3
这类似于:
x = x - (1 + 3)
而不是:
x = (x - 1) + 3
解决方案 13:
x += y
让我们看一下 CPython 为和生成的字节码x = x = y
。(是的,这是依赖于实现的,但它可以让您了解正在实现的语言定义的语义。)
>>> import dis
>>> dis.dis("x += y")
1 0 LOAD_NAME 0 (x)
2 LOAD_NAME 1 (y)
4 INPLACE_ADD
6 STORE_NAME 0 (x)
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
>>> dis.dis("x = x + y")
1 0 LOAD_NAME 0 (x)
2 LOAD_NAME 1 (y)
4 BINARY_ADD
6 STORE_NAME 0 (x)
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
两者之间的唯一区别是用于运算符的字节码: INPLACE_ADD
for+=
和BINARY_ADD
for +
。
BINARY_ADD
是使用x.__add__
(或y.__radd__
如果需要)实现的,因此x = x + y
与 大致相同x = x.__add__(y)
。__add__
和__radd__
通常都返回新实例,而不修改任何一个参数。
INPLACE_ADD
是使用 实现的x.__iadd__
。如果不存在,则x.__add__
用 代替。x.__iadd__
通常返回x
,这样结果STORE_NAME
不会改变 的引用x
,尽管该对象可能已发生变异。(实际上, 的目的INPLACE_ADD
是提供一种变异对象的方法,而不是总是创建一个新对象。)
例如,int.__iadd__
未定义,因此x += 7
当x
是时int
与相同x = x.__add__(y)
,设置x
为的新实例int
。
另一方面,list.__iadd__
是定义的,因此x += [7]
当x
alist
与 相同时x = x.__iadd__([9])
。list.__iadd__
有效地调用extend
将其参数的元素添加到 的末尾。 通过查看重新分配的增强赋值之前和之后 的x
值实际上不可能分辨出来,因为相同的对象被分配给了名称。x
`x`
解决方案 14:
正如其他人所说,+= 运算符是一种快捷方式。例如:
var = 1;
var = var + 1;
#var = 2
也可以这样写:
var = 1;
var += 1;
#var = 2
因此,您不必编写第一个例子,而只需编写第二个例子,这样就可以了。
解决方案 15:
还记得吗,当你在旧计算器中计算 2 和 3 的和时,每次按下 时,你=
都会看到总数增加了 3, 的+=
作用类似。例如:
>>> orange = 2
>>> orange += 3
>>> print(orange)
5
>>> orange +=3
>>> print(orange)
8
解决方案 16:
它基本上是 (变量) = (变量) + x 的简化,例如:
num = num + 2
与以下内容相同:
num += 2
解决方案 17:
减少+=
了使用给定变量添加两个对象时的冗余:
长版本:
a = 10
a = a + 7
print(a) # result is 17
简短版本:
a = 10
a += 7
print(a) # result is 17