在python中+ =做到了什么?

时间:2011-01-30 06:00:29

标签: python operators notation shorthand compound-assignment

我需要知道python中的+ =做了什么。就这么简单。我也很欣赏python中其他简写工具定义的链接。

15 个答案:

答案 0 :(得分:112)

在Python中,+ =是__iadd__特殊方法的糖涂层,如果__add__不存在,则为__radd____iadd__。类的__iadd__方法可以做任何想做的事情。 list对象实现它并使用它迭代一个可迭代对象,将每个元素附加到自身,方法与list的extend方法相同。

这是一个实现__iadd__特殊方法的简单自定义类。使用int初始化对象,然后可以使用+ =运算符添加数字。我在__iadd__中添加了一个print语句来表明它被调用了。此外,__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

希望这有帮助。

答案 1 :(得分:94)

+=使用变量的值添加另一个值,并将新值赋给变量。

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

-=*=/=对减法,乘法和除法的作用相似。

答案 2 :(得分:26)

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

  • -=,从变量中减去一个值,将变量设置为结果
  • *=,将变量和值相乘,使结果成为变量
  • /=,将变量除以值,使结果成为变量
  • %=,对变量执行模数,然后将变量设置为其结果

可能还有其他人。我不是Python程序员。

答案 3 :(得分:24)

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]

参见参考:Why does += behave unexpectedly on lists?

答案 4 :(得分:16)

它在左边添加了右操作数。 x += 2表示x = x + 2

它还可以向列表中添加元素 - 请参阅this SO thread

答案 5 :(得分:14)

这不仅仅是一种语法快捷方式。试试这个:

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 列表方法,但+调用添加,这会对列表执行不同的操作。

答案 6 :(得分:7)

从概念上讲,+ = b"添加" b将结果存储在a中。这种简单的描述将描述许多语言中的+ =运算符。

然而,简单的描述提出了几个问题。

  1. "添加"?
  2. 到底是什么意思?
  3. 我们究竟是什么意思"将结果存储在"? python变量不直接存储值,它们存储对象的引用。
  4. 在python中,这两个问题的答案都取决于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中,使用"字节"观察到类似的行为。和" bytearray"类型。

    最后请注意,即使没有替换对象,也会发生重新分配。如果左侧只是一个变量,这并不重要,但如果您有一个引用可变集合的不可变集合,它可能会导致令人困惑的行为,例如:

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

    在这种情况下,[5]将成功添加到[0]引用的列表中,但之后在代码尝试时将引发异常,并且无法重新分配[0]。

答案 7 :(得分:3)

+= 

只是写作的捷径

numbers = 1
numbers = numbers + 1
print (numbers)   ## 2

所以你会写

numbers = 1
numbers += 1
print (numbers)   ## 2

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

答案 8 :(得分:1)

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

例如如果您有a = 10,则a += 5为:a = a + 5

因此,“ a”现在等于15。

答案 9 :(得分:1)

请注意,x += yx = x + y是不同的,在某些情况下,由于operator precedence加上总是首先评估右侧的事实而包含了附加运算符,例如

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

答案 10 :(得分:0)

正如其他人所说,+ =运算符是一种捷径。 一个例子:

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

也可以这样写:

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

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

答案 11 :(得分:0)

请记住以前用过的时间,例如2& 3,在您的旧计算器中,每当您点击=时,您看到3添加到总计算中,+=执行类似的工作。例如:

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

答案 12 :(得分:0)

我看到很多使用+ =并带有多个整数的答案。

一个例子:

x -= 1 + 3

这类似于:

x = x - (1 + 3)

而不是:

x = (x - 1) + 3

答案 13 :(得分:0)

根据documentation

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。

请注意,还有

答案 14 :(得分:0)

让我们看看 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 用于 +。< /p>

BINARY_ADD 是使用 x.__add__(或 y.__radd__ 如有必要)实现的,因此 x = x + yx = 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) 相同,设置 xint 的新实例。

另一方面,定义了list.__iadd__,所以当x += [7]x 时,listx = x.__iadd__([9]) 相同。 list.__iadd__ 有效地​​调用 extend 将其参数的元素添加到 x 的末尾。通过查看增强赋值前后 x 的值实际上无法判断 x 被重新赋值,因为 same 对象被分配给名称。< /p>