+= 到底是做什么的?

发布于 2024-10-14 16:44:43 字数 76 浏览 7 评论 0原文

我需要知道 += 在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

我一向站在原地 2024-10-21 16:44:44

我看到很多答案都没有提出将 += 与多个整数一起使用。

一个例子:

x -= 1 + 3

这类似于:

x = x - (1 + 3)

而不是:

x = (x - 1) + 3

I'm seeing a lot of answers that don't bring up using += with multiple integers.

One example:

x -= 1 + 3

This would be similar to:

x = x - (1 + 3)

and not:

x = (x - 1) + 3
×眷恋的温暖 2024-10-21 16:44:44

让我们看一下 CPython 为 x += yx = 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 表示 +=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 += 7xint 时,与 x = x.__add__(y) 相同,将 x 设置为 int 的新实例。

另一方面,定义了 list.__iadd__,因此当 xlistx += [7] > 与 x = x.__iadd__([9]) 相同。 list.__iadd__ 有效地调用 extend 将其参数的元素添加到 x 的末尾。实际上不可能通过查看增强赋值之前和之后 x 的值来判断 x 是否已重新分配,因为相同对象是分配给名称。

Let's look at the byte code that CPython generates for x += y and x = x = y. (Yes, this is implementation-depenent, but it gives you an idea of the language-defined semantics being implemented.)

>>> 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

The only difference between the two is the bytecode used for the operator: INPLACE_ADD for +=, and BINARY_ADD for +.

BINARY_ADD is implemented using x.__add__ (or y.__radd__ if necessary), so x = x + y is roughly the same as x = x.__add__(y). Both __add__ and __radd__ typically return new instances, without modifying either argument.

INPLACE_ADD is implemented using x.__iadd__. If that does not exist, then x.__add__ is used in its place. x.__iadd__ typically returns x, so that the resulting STORE_NAME does not change the referent of x, though that object may have been mutated. (Indeed, the purpose of INPLACE_ADD is to provide a way to mutate an object rather than always create a new object.)

For example, int.__iadd__ is not defined, so x += 7 when x is an int is the same as x = x.__add__(y), setting x to a new instance of int.

On the other hand, list.__iadd__ is defined, so x += [7] when x is a list is the same as x = x.__iadd__([9]). list.__iadd__ effectively calls extend to add the elements of its argument to the end of x. It's not really possible to tell by looking at the value of x before and after the augmented assignment that x was reassigned, because the same object was assigned to the name.

非要怀念 2024-10-21 16:44:44

正如其他人也所说, += 运算符是一个快捷方式。
一个例子:

var = 1;
var = var + 1;
#var = 2

也可以这样写:

var = 1;
var += 1;
#var = 2

所以你不用写第一个例子,而是写第二个例子,这样就可以了。

As others also said, the += operator is a shortcut.
An example:

var = 1;
var = var + 1;
#var = 2

It could also be written like so:

var = 1;
var += 1;
#var = 2

So instead of writing the first example, you can just write the second one, which would work just fine.

终陌 2024-10-21 16:44:44

还记得您以前进行求和时的情况吗,例如 2 & 3、在旧计算器中,每次点击 = 时,您都会看到总数中添加了 3,+= 执行类似的工作。例子:

>>> orange = 2
>>> orange += 3
>>> print(orange)
5
>>> orange +=3
>>> print(orange)
8

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:

>>> orange = 2
>>> orange += 3
>>> print(orange)
5
>>> orange +=3
>>> print(orange)
8
萌梦深 2024-10-21 16:44:44

它基本上是 (variable) = (variable) + x 的简化
例如:

num = num + 2

等同于:

num += 2

It’s basically a simplification of saying (variable) = (variable) + x
For example:

num = num + 2

Is the same as:

num += 2
马蹄踏│碎落叶 2024-10-21 16:44:44

+= 减少了使用给定变量添加两个对象时的冗余:

长版本:

a = 10
a = a + 7
print(a)  # result is 17

短版本:

a = 10
a += 7
print(a)  # result is 17

The += cuts down on the redundancy in adding two objects with a given variable:

Long Version:

a = 10
a = a + 7
print(a)  # result is 17

Short Version:

a = 10
a += 7
print(a)  # result is 17
巡山小妖精 2024-10-21 16:44:43

在 Python 中,+=__iadd__ 特殊方法的糖衣,或者 __add____radd__ if __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

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.

>>> 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
似最初 2024-10-21 16:44:43

+= 将另一个值与变量的值相加,并将新值赋给变量。

>>> x = 3
>>> x += 2
>>> print x
5

-=*=/= 的减法、乘法和除法类似。

+= adds another value with the variable's value and assigns the new value to the variable.

>>> x = 3
>>> x += 2
>>> print x
5

-=, *=, /= does similar for subtraction, multiplication and division.

苦妄 2024-10-21 16:44:43

x += 5 与 Python 中的 x = x + 5 并不完全相同。

请注意:

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]

请参阅参考:为什么 += 的行为意外出现在列表中?

x += 5 is not exactly the same as saying x = x + 5 in Python.

Note here:

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]

See for reference: Why does += behave unexpectedly on lists?

伤感在游骋 2024-10-21 16:44:43

+= 向变量添加一个数字,并在此过程中更改变量本身(而 + 则不会)。与此类似,还有以下内容也修改变量:

  • -=,从变量中减去一个值,将变量设置为结果
  • *=,将变量相乘并一个值,使结果成为变量
  • /=,将变量除以值,使结果成为变量
  • %=,对变量执行模运算,然后使用变量被设置为它的结果

可能还有其他的。我不是 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 it

There may be others. I am not a Python programmer.

好久不见√ 2024-10-21 16:44:43

它不仅仅是一个语法糖。试试这个:

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__()代码>一。他们用列表做不同的事情。

It is not mere a syntactic sugar. Try this:

x = []                 # empty list
x += "something"       # iterates over the string and appends to list
print(x)               # ['s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g']

versus

x = []                 # empty list
x = x + "something"    # TypeError: can only concatenate list (not "str") to list

The += operator invokes the __iadd__() list method, while + one invokes the __add__() one. They do different things with lists.

半窗疏影 2024-10-21 16:44:43

它将右侧操作数添加到左侧。 x += 2 表示 x = x + 2

它也可以将元素添加到列表中 - 请参阅 这个SO线程

It adds the right operand to the left. x += 2 means x = x + 2

It can also add elements to a list -- see this SO thread.

人心善变 2024-10-21 16:44:43

理论上,a += b 将 b“添加”到 a,并将结果存储在 a 中。这种简单化的描述可以描述许多语言中的 += 运算符。

然而,这种简单化的描述引发了一些问题。

  1. 我们所说的“添加”到底是什么意思?
  2. “将结果存储在 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] 但失败时,将引发异常。

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.

  1. What exactly do we mean by "adding"?
  2. What exactly do we mean by "storing the result in a"? python variables don't store values directly they store references to objects.

In python the answers to both of these questions depend on the data type of a.


So what exactly does "adding" mean?

  • For numbers it means numeric addition.
  • For lists, tuples, strings etc it means concatenation.

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.

def dostuff(a):
    b = a
    a += (3,4)
    print(repr(a)+' '+repr(b))

dostuff((1,2))
dostuff([1,2])

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:

a = ([1,2],[3,4])
a[0] += [5]

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].

岁吢 2024-10-21 16:44:43

注意:在某些情况下,由于 运算符优先级 结合右侧始终首先计算的事实,例如,

>>> x = 2
>>> x += 2 and 1
>>> x
3

>>> x = 2
>>> x = x + 2 and 1
>>> x
1

请注意第一种情况 Expand to:

>>> x = 2
>>> x = x + (2 and 1)
>>> x
3

您更有可能在“现实世界”中使用其他运算符遇到此问题,例如

x *= 2 + 1 == x = x * (2 + 1) != x = x * 2 + 1

Note x += y is not the same as x = 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.

>>> x = 2
>>> x += 2 and 1
>>> x
3

>>> x = 2
>>> x = x + 2 and 1
>>> x
1

Note the first case expand to:

>>> x = 2
>>> x = x + (2 and 1)
>>> x
3

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

注定孤独终老 2024-10-21 16:44:43

简短的答案是 += 可以翻译为“将 += 右侧的任何内容添加到 += 左侧的变量中。

前任。如果您有 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 then a += 5 would be: a = a + 5

So, "a" now equal to 15.

素罗衫 2024-10-21 16:44:43

根据 文档

x += y 等价于 x = operator.iadd(x, y)。另一种方式
也就是说 z = operator.iadd(x, y) 相当于
复合语句 z = x; z += y

因此,x += 3x = x + 3 相同。

x = 2

x += 3

print(x)

将输出 5。

请注意,还有

According to the documentation

x += y is equivalent to x = operator.iadd(x, y). Another way to
put it is to say that z = operator.iadd(x, y) is equivalent to the
compound statement z = x; z += y.

So x += 3 is the same as x = x + 3.

x = 2

x += 3

print(x)

will output 5.

Notice that there are also

江南烟雨〆相思醉 2024-10-21 16:44:43

+= 只是编写的快捷方式

number = 4
number = number + 1

因此,您可以编写

numbers = 4
numbers += 1

两种方式都是正确的,但示例二可以帮助您编写更少的代码

+= is just a shortcut for writing

number = 4
number = number + 1

So instead you would write

numbers = 4
numbers += 1

Both ways are correct but example two helps you write a little less code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文