+= 到底是做什么的?
我需要知道 +=
在 Python 中做什么。就是这么简单。我也希望链接到 Python 中其他速记工具的定义。
I need to know what +=
does in Python. It's that simple. I also would appreciate links to definitions of other shorthand tools in Python.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
我看到很多答案都没有提出将 += 与多个整数一起使用。
一个例子:
这类似于:
而不是:
I'm seeing a lot of answers that don't bring up using += with multiple integers.
One example:
This would be similar to:
and not:
让我们看一下 CPython 为
x += y
和x = x = y
生成的字节码。 (是的,这是依赖于实现的,但它让您了解正在实现的语言定义的语义。)两者之间的唯一区别是用于运算符的字节码:
INPLACE_ADD
表示+=
,BINARY_ADD
表示+
。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
是list
时x += [7]
> 与x = x.__iadd__([9])
相同。list.__iadd__
有效地调用extend
将其参数的元素添加到x
的末尾。实际上不可能通过查看增强赋值之前和之后x
的值来判断x
是否已重新分配,因为相同对象是分配给名称。Let's look at the byte code that CPython generates for
x += y
andx = x = y
. (Yes, this is implementation-depenent, but it gives you an idea of the language-defined semantics being implemented.)The only difference between the two is the bytecode used for the operator:
INPLACE_ADD
for+=
, andBINARY_ADD
for+
.BINARY_ADD
is implemented usingx.__add__
(ory.__radd__
if necessary), sox = x + y
is roughly the same asx = x.__add__(y)
. Both__add__
and__radd__
typically return new instances, without modifying either argument.INPLACE_ADD
is implemented usingx.__iadd__
. If that does not exist, thenx.__add__
is used in its place.x.__iadd__
typically returnsx
, so that the resultingSTORE_NAME
does not change the referent ofx
, though that object may have been mutated. (Indeed, the purpose ofINPLACE_ADD
is to provide a way to mutate an object rather than always create a new object.)For example,
int.__iadd__
is not defined, sox += 7
whenx
is anint
is the same asx = x.__add__(y)
, settingx
to a new instance ofint
.On the other hand,
list.__iadd__
is defined, sox += [7]
whenx
is alist
is the same asx = x.__iadd__([9])
.list.__iadd__
effectively callsextend
to add the elements of its argument to the end ofx
. It's not really possible to tell by looking at the value ofx
before and after the augmented assignment thatx
was reassigned, because the same object was assigned to the name.正如其他人也所说, += 运算符是一个快捷方式。
一个例子:
也可以这样写:
所以你不用写第一个例子,而是写第二个例子,这样就可以了。
As others also said, the += operator is a shortcut.
An example:
It could also be written like so:
So instead of writing the first example, you can just write the second one, which would work just fine.
还记得您以前进行求和时的情况吗,例如 2 & 3、在旧计算器中,每次点击
=
时,您都会看到总数中添加了 3,+=
执行类似的工作。例子:Remember when you used to sum, for example 2 & 3, in your old calculator and every time you hit the
=
you see 3 added to the total, the+=
does similar job. Example:它基本上是 (variable) = (variable) + x 的简化
例如:
等同于:
It’s basically a simplification of saying (variable) = (variable) + x
For example:
Is the same as:
+=
减少了使用给定变量添加两个对象时的冗余:长版本:
短版本:
The
+=
cuts down on the redundancy in adding two objects with a given variable:Long Version:
Short Version:
在 Python 中,
+=
是__iadd__
特殊方法的糖衣,或者__add__
或__radd__
if__iadd__
不存在。类的__iadd__
方法可以做任何它想做的事情。列表对象实现它并使用它来迭代可迭代对象,以与列表的扩展方法相同的方式将每个元素附加到自身。下面是一个简单的自定义类,它实现了 __iadd__ 特殊方法。您可以使用 int 初始化该对象,然后可以使用 += 运算符来添加数字。我在
__iadd__
中添加了一条打印语句以表明它被调用。另外,__iadd__
预计会返回一个对象,因此我返回了自身加上其他数字的加法,这在本例中是有意义的。In Python,
+=
is sugar coating for the__iadd__
special method, or__add__
or__radd__
if__iadd__
isn't present. The__iadd__
method of a class can do anything it wants. The list object implements it and uses it to iterate over an iterable object appending each element to itself in the same way that the list's extend method does.Here's a simple custom class that implements the
__iadd__
special method. You initialize the object with an int, then can use the+=
operator to add a number. I've added a print statement in__iadd__
to show that it gets called. Also,__iadd__
is expected to return an object, so I returned the addition of itself plus the other number which makes sense in this case.+=
将另一个值与变量的值相加,并将新值赋给变量。-=
、*=
、/=
的减法、乘法和除法类似。+=
adds another value with the variable's value and assigns the new value to the variable.-=
,*=
,/=
does similar for subtraction, multiplication and division.x += 5
与 Python 中的x = x + 5
并不完全相同。请注意:
请参阅参考:为什么 += 的行为意外出现在列表中?
x += 5
is not exactly the same as sayingx = x + 5
in Python.Note here:
See for reference: Why does += behave unexpectedly on lists?
+=
向变量添加一个数字,并在此过程中更改变量本身(而+
则不会)。与此类似,还有以下内容也修改变量:-=
,从变量中减去一个值,将变量设置为结果*=
,将变量相乘并一个值,使结果成为变量/=
,将变量除以值,使结果成为变量%=
,对变量执行模运算,然后使用变量被设置为它的结果可能还有其他的。我不是 Python 程序员。
+=
adds a number to a variable, changing the variable itself in the process (whereas+
would not). Similar to this, there are the following that also modifies the variable:-=
, subtracts a value from variable, setting the variable to the result*=
, multiplies the variable and a value, making the outcome the variable/=
, divides the variable by the value, making the outcome the variable%=
, performs modulus on the variable, with the variable then being set to the result of itThere may be others. I am not a Python programmer.
它不仅仅是一个语法糖。试试这个:
与
+=
运算符调用__iadd__()
列表方法,而+
运算符调用__add__()
代码>一。他们用列表做不同的事情。It is not mere a syntactic sugar. Try this:
versus
The
+=
operator invokes the__iadd__()
list method, while+
one invokes the__add__()
one. They do different things with lists.它将右侧操作数添加到左侧。
x += 2
表示x = x + 2
它也可以将元素添加到列表中 - 请参阅 这个SO线程。
It adds the right operand to the left.
x += 2
meansx = x + 2
It can also add elements to a list -- see this SO thread.
理论上,a += b 将 b“添加”到 a,并将结果存储在 a 中。这种简单化的描述可以描述许多语言中的 += 运算符。
然而,这种简单化的描述引发了一些问题。
在 python 中,这两个问题的答案取决于 a 的数据类型。
那么“添加”到底是什么意思呢?
请注意,对于列表,+= 比 + 更灵活,列表上的 + 运算符需要另一个列表,但 += 运算符将接受任何可迭代对象。
那么“将值存储在a中”是什么意思呢?
如果对象是可变的,则鼓励(但不要求)就地执行修改。因此 a 指向之前的同一个对象,但该对象现在具有不同的内容。
如果对象是不可变的,那么它显然无法就地执行修改。一些可变对象也可能没有就地“添加”操作的实现。在这种情况下,变量“a”将被更新为指向包含加法运算结果的新对象。
从技术上讲,这是通过首先查找
__IADD__
来实现的,如果未实现,则尝试__ADD__
,最后查找__RADD__
。在 python 中对变量使用 += 时需要小心,因为我们不确定确切的类型,特别是当我们不确定类型是否可变时。例如,考虑以下代码。
当我们使用元组调用 dostuff 时,元组将作为 += 操作的一部分被复制,因此 b 不受影响。然而,当我们使用列表调用它时,列表会被就地修改,因此 a 和 b 都会受到影响。
在 python 3 中,“bytes”和“bytearray”类型也有类似的行为。
最后请注意,即使未替换对象,也会发生重新分配。如果左侧只是一个变量,这并不重要,但当您有一个引用可变集合的不可变集合时,它可能会导致令人困惑的行为,例如:
在这种情况下,[5]将成功添加到由a[0],但随后当代码尝试重新分配 a[0] 但失败时,将引发异常。
Notionally a += b "adds" b to a storing the result in a. This simplistic description would describe the += operator in many languages.
However the simplistic description raises a couple of questions.
In python the answers to both of these questions depend on the data type of a.
So what exactly does "adding" mean?
Note that for lists += is more flexible than +, the + operator on a list requires another list, but the += operator will accept any iterable.
So what does "storing the value in a" mean?
If the object is mutable then it is encouraged (but not required) to perform the modification in-place. So a points to the same object it did before but that object now has different content.
If the object is immutable then it obviously can't perform the modification in-place. Some mutable objects may also not have an implementation of an in-place "add" operation . In this case the variable "a" will be updated to point to a new object containing the result of an addition operation.
Technically this is implemented by looking for
__IADD__
first, if that is not implemented then__ADD__
is tried and finally__RADD__
.Care is required when using += in python on variables where we are not certain of the exact type and in particular where we are not certain if the type is mutable or not. For example consider the following code.
When we invoke dostuff with a tuple then the tuple is copied as part of the += operation and so b is unaffected. However when we invoke it with a list the list is modified in place, so both a and b are affected.
In python 3, similar behaviour is observed with the "bytes" and "bytearray" types.
Finally note that reassignment happens even if the object is not replaced. This doesn't matter much if the left hand side is simply a variable but it can cause confusing behaviour when you have an immutable collection referring to mutable collections for example:
In this case [5] will successfully be added to the list referred to by a[0] but then afterwards an exception will be raised when the code tries and fails to reassign a[0].
注意:在某些情况下,由于 运算符优先级 结合右侧始终首先计算的事实,例如,
请注意第一种情况 Expand to:
您更有可能在“现实世界”中使用其他运算符遇到此问题,例如
x *= 2 + 1
==x = x * (2 + 1)
!=x = x * 2 + 1
Note
x += y
is not the same asx = x + y
in some situations where an additional operator is included because of the operator precedence combined with the fact that the right hand side is always evaluated first, e.g.Note the first case expand to:
You are more likely to encounter this in the 'real world' with other operators, e.g.
x *= 2 + 1
==x = x * (2 + 1)
!=x = x * 2 + 1
简短的答案是
+=
可以翻译为“将 += 右侧的任何内容添加到 += 左侧的变量中。前任。如果您有
a = 10
,则a += 5
将是:a = a + 5
因此,“a”现在等于 15。
The short answer is
+=
can be translated as "add whatever is to the right of the += to the variable on the left of the +=".Ex. If you have
a = 10
thena += 5
would be:a = a + 5
So, "a" now equal to 15.
根据 文档
因此,
x += 3
与x = x + 3
相同。将输出 5。
请注意,还有
According to the documentation
So
x += 3
is the same asx = x + 3
.will output 5.
Notice that there are also
+=
只是编写的快捷方式因此,您可以编写
两种方式都是正确的,但示例二可以帮助您编写更少的代码
+=
is just a shortcut for writingSo instead you would write
Both ways are correct but example two helps you write a little less code