免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Python 表達(dá)式 i += x 與 i = i + x 等價(jià)嗎?

題圖:unsplash.com by Dmitry Pavlov

Python 表達(dá)式 i += x i = i + x 等價(jià)嗎?如果你的回答是yes,那么恭喜你正確了50%,為什么說(shuō)只對(duì)了一半呢? 按照我們的一般理解它們倆是等價(jià)的,整數(shù)操作時(shí)兩者沒什么異同,但是對(duì)于列表操作,是不是也一樣呢?先看下面兩段代碼:

代碼1

>>> l1 = range(3)>>> l2 = l1>>> l2 += [3]>>> l1[0, 1, 2, 3]>>> l2[0, 1, 2, 3]

代碼2

>>> l1 = range(3)>>> l2 = l1>>> l2 = l2 + [3]>>> l1[0, 1, 2]>>> l2[0, 1, 2, 3]

代碼1與代碼2中的 l2 的值是一樣的,但是 l1 的值卻不一樣,說(shuō)明 i += x 與 i = i + x 是不等價(jià)的,那什么情況下等價(jià),什么情況下不等價(jià)呢?

弄清楚這個(gè)問(wèn)題之前,首選得明白兩個(gè)概念:可變對(duì)象與不可變對(duì)象。

在 Python 中任何對(duì)象都有的三個(gè)通用屬性:唯一標(biāo)識(shí)、類型、值。

唯一標(biāo)識(shí):用于標(biāo)識(shí)對(duì)象的在內(nèi)存中唯一性,它在對(duì)象創(chuàng)建之后就不會(huì)再改變,函數(shù) id() 可以查看對(duì)象的唯一標(biāo)識(shí)

類型:決定了該對(duì)象支持哪些操作,不同類型的對(duì)象支持的操作就不一樣,比如列表可以有l(wèi)ength屬性,而整數(shù)沒有。同樣地對(duì)象的類型一旦確定了就不會(huì)再變,函數(shù) type() 可以返回對(duì)象的類型信息。

對(duì)象的 與唯一標(biāo)識(shí)不一樣,并不是所有的對(duì)象的值都是一成不變的,有些對(duì)象的值可以通過(guò)某些操作發(fā)生改變,值可以變化的對(duì)象稱之為可變對(duì)象(mutable),值不能改變的對(duì)象稱之為不可變對(duì)象(immutable)

不可變對(duì)象(immutable)

對(duì)于不可變對(duì)象,值永遠(yuǎn)是剛開始創(chuàng)建時(shí)候的值,對(duì)該對(duì)象做的任何操作都會(huì)導(dǎo)致一個(gè)新的對(duì)象的創(chuàng)建。

>>> a = 1>>> id(a)32574568>>> a += 1>>> id(a)32574544

整數(shù) “1” 是一個(gè)不可變對(duì)象,最初賦值的時(shí)候, a 指向的是整數(shù)對(duì)象 1 ,但對(duì)變量a執(zhí)行 += 操作后, a 指向另外一個(gè)整數(shù)對(duì)象 2 ,但對(duì)象 1 還是在那里沒有發(fā)生任何變化,而 變量 a 已經(jīng)指向了一個(gè)新的對(duì)象2。常見的不可變對(duì)象有:int、tuple、set、str。

可變對(duì)象(mutable)

可變對(duì)象的值可以通過(guò)某些操作動(dòng)態(tài)的改變,比如列表對(duì)象,可以通過(guò)append方法不斷地往列表中添加元素,該列表的值就在不斷的處于變化中,一個(gè)可變對(duì)象賦值給兩個(gè)變量時(shí),他們共享同一個(gè)實(shí)例對(duì)象,指向相同的內(nèi)存地址,對(duì)其中任何一個(gè)變量操作時(shí),同時(shí)也會(huì)影響另外一個(gè)變量。

>>> x = range(3)>>> y = x>>> id(x)139726103041232>>> id(y)139726103041232>>> x.append(3)>>> x[0, 1, 2, 3]>>> y[0, 1, 2, 3]>>> id(x)139726103041232>>> id(y)139726103041232

執(zhí)行append操作后,對(duì)象的內(nèi)存地址不會(huì)改變,x、y 依然指向的是原來(lái)同一個(gè)對(duì)象,只不過(guò)是他的值發(fā)生了變化而已。

理解完可變對(duì)象與不可變對(duì)象后,回到問(wèn)題本身, += 與 + 的區(qū)別在哪里呢?

+= 操作首先會(huì)嘗試調(diào)用對(duì)象的  __iadd__ 方法,如果沒有該方法,那么嘗試調(diào)用 __add__ 方法 ,先來(lái)看看這兩個(gè)方法有什么區(qū)別

__add__和 __ iadd __ 的區(qū)別

  • __add__ 方法接收兩個(gè)參數(shù),返回它們的和,兩個(gè)參數(shù)的值均不會(huì)改變。

  • __iadd__ 方法同樣接收兩個(gè)參數(shù),但它是屬于 in-place 操作,就是說(shuō)它會(huì)改變第一個(gè)參數(shù)的值,因?yàn)檫@需要對(duì)象是可變的,所以對(duì)于不可變對(duì)象沒有__iadd__方法。

>>> hasattr(int, '__iadd__')False>>> hasattr(list, '__iadd__')True

顯然,整數(shù)對(duì)象是沒有__iadd__的,而列表對(duì)象提供了__iadd__方法。

>>> l2 += [3]  # 代碼1:使用__iadd__,l2的值原地修改

代碼1中的 += 操作調(diào)用的是__iadd __ 方法,他會(huì)原地修改l2指向的那個(gè)對(duì)象本身的值

>>> l2 = l2 + [3]  # 代碼2:調(diào)用 __add__,創(chuàng)建了一個(gè)新的列表,賦值給了l2

而代碼2中的 + 操作調(diào)用的是 __add __ 方法,該方法會(huì)返回一個(gè)新的對(duì)象,原來(lái)的對(duì)象保持不變,l1還是指向原來(lái)的對(duì)象,而l2已經(jīng)指向一個(gè)新的對(duì)象。

以上就是表達(dá)式 i += x 與 i = i + x 的區(qū)別。因此對(duì)于列表進(jìn)行 += 操作時(shí),會(huì)存在潛在的bug,因?yàn)閘1會(huì)因?yàn)閘2的變化而發(fā)生改變,就像函數(shù)的參數(shù)不宜使用可變對(duì)象作為關(guān)鍵字參數(shù)一樣。

來(lái)自:http://mp.weixin.qq.com/s/jluii9YIvfhKd_tPecfTaw

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python中的a+=b和a=a+b之間的區(qū)別是什么?
你知道Python中a = b和a = a b的結(jié)果是不一樣的嗎?
你學(xué)習(xí) Python 的時(shí)候,用到舒服姿勢(shì)了么?
好的代碼可以自己說(shuō)話
「19」如何避開Python函數(shù)的參數(shù)傳遞的各種坑(一)?
麻省理工教授將Python基礎(chǔ)總結(jié)成千行代碼,讓Python入門更簡(jiǎn)單!
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服