最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Python中表達(dá)式i += x與i = i + x是否等價(jià)

 更新時(shí)間:2017年02月08日 11:57:02   作者:一個(gè)程序員的微站  
這篇文章主要介紹了關(guān)于Python中表達(dá)式i += x與i = i + x是否等價(jià)的相關(guān)資料,文中通過示例代碼介紹的很詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。

前言

最近看到一個(gè)題目,看似很簡(jiǎn)單,其實(shí)里面有很深的意義,題目是Python 表達(dá)式 i += x 與 i = i + x 等價(jià)嗎?如果你的回答是yes,那么恭喜你正確了50%,為什么說只對(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的值卻不一樣,說明 i += x 與 i = i + x 是不等價(jià)的,那什么情況下等價(jià),什么情況下不等價(jià)呢?

弄清楚這個(gè)問題之前,首選得明白兩個(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ì)象的值可以通過某些操作發(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ì)象的值可以通過某些操作動(dòng)態(tài)的改變,比如列表對(duì)象,可以通過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 依然指向的是原來同一個(gè)對(duì)象,只不過是他的值發(fā)生了變化而已。


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

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

__add__和 __iadd__ 的區(qū)別

  1. __add__ 方法接收兩個(gè)參數(shù),返回它們的和,兩個(gè)參數(shù)的值均不會(huì)改變。
  2. __iadd__ 方法同樣接收兩個(gè)參數(shù),但它是屬于 in-place 操作,就是說它會(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ì)象,原來的對(duì)象保持不變,l1還是指向原來的對(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ù)一樣。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關(guān)文章

  • 深入淺析Python中join 和 split詳解(推薦)

    深入淺析Python中join 和 split詳解(推薦)

    這篇文章主要介紹了Python中join 和 split詳解的相關(guān)資料,本文還通過一個(gè)示例給大家介紹python join 和 split方法 的使用,需要的朋友可以參考下
    2016-06-06
  • OpenCV?NAO機(jī)器人輔助撿球丟球流程分析

    OpenCV?NAO機(jī)器人輔助撿球丟球流程分析

    這篇文章主要介紹了OpenCV?NAO機(jī)器人輔助撿球丟球,本項(xiàng)目使用NAO機(jī)器人識(shí)別球并撿起,然后將其扔到指定位置,主要涉及圖像的獲取、濾波、目標(biāo)物體定位和NAO機(jī)器人的運(yùn)動(dòng)控制,需要的朋友可以參考下
    2022-05-05
  • Python之求任意正整數(shù)的階乘方式

    Python之求任意正整數(shù)的階乘方式

    這篇文章主要介紹了Python之求任意正整數(shù)的階乘方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python爬蟲headers處理及網(wǎng)絡(luò)超時(shí)問題解決方案

    Python爬蟲headers處理及網(wǎng)絡(luò)超時(shí)問題解決方案

    這篇文章主要介紹了Python爬蟲headers處理及網(wǎng)絡(luò)超時(shí)問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Python pickle模塊進(jìn)行序列化的實(shí)現(xiàn)示例

    Python pickle模塊進(jìn)行序列化的實(shí)現(xiàn)示例

    pickle模塊是一個(gè)用于實(shí)現(xiàn)數(shù)據(jù)序列化與反序列化的強(qiáng)大工具,本文就來介紹一下Python pickle模塊進(jìn)行序列化的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-01-01
  • PyCharm調(diào)用matplotlib繪圖時(shí)圖像彈出問題詳解

    PyCharm調(diào)用matplotlib繪圖時(shí)圖像彈出問題詳解

    這篇文章主要給大家介紹了關(guān)于PyCharm調(diào)用matplotlib繪圖時(shí)圖像彈出問題的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用PyCharm具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-07-07
  • IPython庫(kù)中的display函數(shù)的簡(jiǎn)介、使用方法、應(yīng)用案例詳細(xì)攻略

    IPython庫(kù)中的display函數(shù)的簡(jiǎn)介、使用方法、應(yīng)用案例詳細(xì)攻略

    display 函數(shù)可以接受一個(gè)或多個(gè)參數(shù),每個(gè)參數(shù)都是一個(gè) Python 對(duì)象。它會(huì)自動(dòng)根據(jù)對(duì)象的類型選擇合適的顯示方式,并在 Jupyter Notebook 中顯示出來,這篇文章主要介紹了IPython庫(kù)中的display函數(shù)的簡(jiǎn)介、使用方法、應(yīng)用案例詳細(xì)攻略,需要的朋友可以參考下
    2023-04-04
  • 解決Mac下使用python的坑

    解決Mac下使用python的坑

    今天小編就為大家分享一篇解決Mac下使用python的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • python?pdb調(diào)試器及使用方法

    python?pdb調(diào)試器及使用方法

    這篇文章主要介紹了python?pdb調(diào)試器及使用方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Python Json與pickle模塊序列化使用介紹

    Python Json與pickle模塊序列化使用介紹

    這篇文章主要為大家介紹了Python中常用的兩個(gè)序列化模塊:pickle序列化和json序列化。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2022-10-10

最新評(píng)論

松溪县| 房山区| 松原市| 常州市| 永寿县| 长顺县| 海丰县| 苍梧县| 克山县| 沧州市| 汉源县| 文水县| 东莞市| 三门县| 开鲁县| 合江县| 靖州| 襄城县| 新巴尔虎左旗| 松江区| 中西区| 九江县| 宁晋县| 永安市| 昂仁县| 石景山区| 新蔡县| 永和县| 藁城市| 盐城市| 潜山县| 铁力市| 枝江市| 桓台县| 天台县| 安国市| 白玉县| 福清市| 鞍山市| 旬邑县| 溧阳市|