簡體   English   中英

+= 到底是做什么的?

[英]What exactly does += do?

我需要知道+=在 Python 中的作用。 就這么簡單。 我也希望鏈接到 Python 中其他速記工具的定義。

在 Python 中,+= 是__iadd__特殊方法的__radd__如果__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

希望這可以幫助。

+=將另一個值與變量的值相加,並將新值分配給變量。

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

-= , *= , /=對減法、乘法和除法的作用類似。

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]

請參閱參考: 為什么 += 在列表上表現出乎意料?

+=向變量添加一個數字,在過程中更改變量本身(而+不會)。 與此類似,還有以下內容也修改了變量:

  • -= ,從變量中減去一個值,將變量設置為結果
  • *= ,將變量和一個值相乘,使結果成為變量
  • /= ,將變量除以值,使結果成為變量
  • %= ,對變量執行取模,然后將變量設置為其結果

可能還有其他人。 我不是 Python 程序員。

它不僅僅是一個語法糖。 嘗試這個:

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

它將右側的操作數添加到左側。 x += 2表示x = x + 2

它還可以將元素添加到列表 - 請參閱此 SO 線程

理論上 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] 失敗時將引發異常。

注意x += yx = 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

簡短的回答是+=可以翻譯為“將 += 右側的任何內容添加到 += 左側的變量中。

前任。 如果您有a = 10那么a += 5將是: a = a + 5

所以,“a”現在等於 15。

+=只是書寫的捷徑

number = 4
number = number + 1

所以你會寫

numbers = 4
numbers += 1

兩種方式都是正確的,但示例二可以幫助您編寫更少的代碼

根據文檔

x += y等價於x = operator.iadd(x, y) 另一種說法是z = operator.iadd(x, y)等價於復合語句z = x; z += y z = x; z += y

所以x += 3x = x + 3

x = 2

x += 3

print(x)

將輸出 5。

請注意,還有

正如其他人所說, += 運算符是一種快捷方式。 一個例子:

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

也可以這樣寫:

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

因此,您可以編寫第二個,而不是編寫第一個示例,這會很好用。

請記住,當您過去在舊計算器中進行求和時,例如 2 和 3,每次點擊=您都會看到總數增加了 3, +=作用類似。 例子:

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

我看到很多答案都沒有提出將 += 與多個整數一起使用。

一個例子:

x -= 1 + 3

這將類似於:

x = x - (1 + 3)

並不是:

x = (x - 1) + 3

讓我們看看 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 + yx = x.__add__(y)大致相同。 __add____radd__通常都返回新實例,而不修改任何一個參數。

INPLACE_ADD是使用x.__iadd__ 如果不存在,則使用x.__add__代替它。 x.__iadd__通常返回x ,因此生成的STORE_NAME不會更改x的指示對象,盡管該對象可能已發生變異。 (實際上, INPLACE_ADD的目的是提供一種改變對象的方法,而不是總是創建一個新對象。)

例如, int.__iadd__未定義,因此當xintx += 7x = x.__add__(y) ,將x設置為int的新實例。

另一方面, list.__iadd__已定義,因此當xlistx += [7]x = x.__iadd__([9]) list.__iadd__有效地調用extend將其參數的元素添加到x的末尾。 通過查看增強賦值前后x的值實際上無法判斷x被重新賦值,因為同一個對象被賦值給名稱。

+=減少了用給定變量添加兩個對象的冗余:

長版:

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

精簡版:

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

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

num = num + 2

是相同的:

num += 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM