編程學(xué)習(xí)-有趣python-整數(shù)比較/附pycharm高級版激活教程

在 Python 中一切都是對象,毫無例外整數(shù)也是對象,對象之間比較是否相等可以用==,也可以用is。==和is操作的區(qū)別是:

is比較的是兩個(gè)對象的id值是否相等,也就是比較倆對象是否為同一個(gè)實(shí)例對象,是否指向同一個(gè)內(nèi)存地址。
==比較的是兩個(gè)對象的內(nèi)容是否相等,默認(rèn)會調(diào)用對象的__eq__()方法。
清楚is和==的區(qū)別之后,對此也許你有可能會遇到下面的這些困惑,于是就有了這樣一篇文章,試圖把Python中一些隱晦的東西趴出來,希望對你有一定的幫助。我們先來看兩段代碼:
片段一:

>>> a = 256
>>> b = 256
>>> a == b
True
>>>

片段二:

>>> a = 256
>>> b = 256
>>> a is b
True
>>>

在交互式命令行執(zhí)行上面兩段代碼,代碼片段一中的a==b返回True很好理解,因?yàn)閮蓚€(gè)對象的值都是256,對于片段二,a is b也返回True,這說明a和b是指向同一個(gè)對象的,可以檢查一下他們的id值是否相等:

>>> id(a)
8213296
>>> id(b)
8213296
>>> 

結(jié)果證明他倆的確是同一個(gè)對象,指向的是同一個(gè)內(nèi)存地址。那是不是所有的整數(shù)對象只要兩個(gè)對象的值(內(nèi)容)相等,它們就是同一個(gè)實(shí)例對象呢?換句話說,對于整數(shù)對象只要==返回True,is操作也會返回True嗎?帶著這個(gè)問題來看下面這兩段代碼:
片段一:

>>> a = 257
>>> b = 257
>>> a == b
True
>>>

片段二:

>>> a = 257
>>> b = 257
>>> a is b
False
>>>

對于257,a is b返回的竟然是False,結(jié)果可能在你的意料之中,也有可能出乎你的意料,但不管怎么,我們還是要刨根問底,找出問題的真相。

解惑一

出于對性能的考慮,Python內(nèi)部做了很多的優(yōu)化工作,對于整數(shù)對象,Python把一些頻繁使用的整數(shù)對象緩存起來,保存到一個(gè)叫small_ints的鏈表中,在Python的整個(gè)生命周期內(nèi),任何需要引用這些整數(shù)對象的地方,都不再重新創(chuàng)建新的對象,而是直接引用緩存中的對象。Python把這些可能頻繁使用的整數(shù)對象規(guī)定在范圍[-5, 256]之間的小對象放在small_ints中,但凡是需要用些小整數(shù)時(shí),就從這里面取,不再去臨時(shí)創(chuàng)建新的對象。因?yàn)?57不再小整數(shù)范圍內(nèi),因此盡管a和b的值是一樣,但是他們在Python內(nèi)部卻是以兩個(gè)獨(dú)立的對象存在的,各自為政,互不干涉。
弄明白第一個(gè)問題后,我們繼續(xù)在Python交互式命令行中寫一個(gè)函數(shù),再來看下面這段代碼:

片段一:

>>> c = 257
>>> def foo():
...     a = 257
...     b = 257
...     print a is b
...     print a is c
... 
>>> foo()
True
False

呃,什么情況,是的,你沒看錯(cuò),片段一中的這段代碼 a、b 值都是257的情況下,出現(xiàn)了a is b返回True,而a is c 返回的False,a、b、c的值都為257,為什么會出現(xiàn)不同的結(jié)果呢?這對于剛剛好不容易建立起來的認(rèn)知就被徹底否決了嗎,那這段代碼中究竟發(fā)生了什么?難道解惑一中的結(jié)論是錯(cuò)誤的嗎?

解惑二

為了弄清楚這個(gè)問題,我們有必要先理解程序代碼塊的概念。Python程序由代碼塊構(gòu)成,代碼塊作為程序的一個(gè)最小基本單位來執(zhí)行。一個(gè)模塊文件、一個(gè)函數(shù)體、一個(gè)類、交互式命令中的單行代碼都叫做一個(gè)代碼塊。在上面這段代碼中,由兩個(gè)代碼塊構(gòu)成,c = 257作為一個(gè)代碼塊,函數(shù)foo作為另外一個(gè)代碼塊。Python內(nèi)部為了將性能進(jìn)一步的提高,凡是在一個(gè)代碼塊中創(chuàng)建的整數(shù)對象,如果存在一個(gè)值與其相同的對象于該代碼塊中了,那么就直接引用,否則創(chuàng)建一個(gè)新的對象出來。Python出于對性能的考慮,但凡是不可變對象,在同一個(gè)代碼塊中的對象,只有是值相同的對象,就不會重復(fù)創(chuàng)建,而是直接引用已經(jīng)存在的對象。因此,不僅是整數(shù)對象,還有字符串對象也遵循同樣的原則。所以 a is b就理所當(dāng)然的返回True了,而c和a不在同一個(gè)代碼塊中,因此在Python內(nèi)部創(chuàng)建了兩個(gè)值都是257的對象。為了驗(yàn)證剛剛的結(jié)論,我們可以借用dis模塊從字節(jié)碼的角度來看看這段代碼。

>>> import dis
>>> dis.dis(foo)
  2           0 LOAD_CONST               1 (257)
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               1 (257)
              9 STORE_FAST               1 (b)

  4          12 LOAD_FAST                0 (a)
             15 LOAD_FAST                1 (b)
             18 COMPARE_OP               8 (is)
             21 PRINT_ITEM          
             22 PRINT_NEWLINE       

  5          23 LOAD_FAST                0 (a)
             26 LOAD_GLOBAL              0 (c)
             29 COMPARE_OP               8 (is)
             32 PRINT_ITEM          
             33 PRINT_NEWLINE       
             34 LOAD_CONST               0 (None)
             37 RETURN_VALUE

可以看出兩個(gè)257都是從常量池的同一個(gè)位置co_consts[1]獲取的。

總結(jié)

一番長篇大論之后,得出兩點(diǎn)結(jié)論:1、小整數(shù)對象[-5,256]是全局解釋器范圍內(nèi)被重復(fù)使用,永遠(yuǎn)不會被GC回收。2、同一個(gè)代碼塊中的不可變對象,只要值是相等的就不會重復(fù)創(chuàng)建新的對象。似乎這些知識點(diǎn)對日常的工作一點(diǎn)忙也幫不上,因?yàn)槟愀静粫胕s來比較兩個(gè)整數(shù)對象的值是否相等。那為什么還要拿出來討論呢?嗯,程序員學(xué)知識,不應(yīng)該淺嘗輒止,要充分發(fā)揮死磕到底的精神---python之禪



pycharm 高級版激活教程

使用中忽然彈窗收費(fèi),請注意,你點(diǎn)擊驗(yàn)證后,會出現(xiàn)三種驗(yàn)證方式,選擇 license server,輸入 http://idea.liyang.io ,稍等片刻,即可激活??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • http://python.jobbole.com/85231/ 關(guān)于專業(yè)技能寫完項(xiàng)目接著寫寫一名3年工作經(jīng)驗(yàn)的J...
    燕京博士閱讀 7,805評論 1 118
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,740評論 18 399
  • Python簡介 Python歷史 Python 是由 Guido van Rossum 在八十年代末和九十年代初...
    莫名其妙的一生閱讀 1,139評論 0 2
  • 生活給了我們愿望與美好,同時(shí)也給了我們黑暗和扭曲。我有一位同事,全公司公認(rèn)的才女,出口成章,落筆成文,懂生活,愛生...
    奔跑的小青桔閱讀 885評論 1 0
  • 7月11日-12日,兩天時(shí)間里,我們可親可敬的聶老師堅(jiān)持為大家做了極具意義的暑期培訓(xùn)。交流語文教學(xué)與心...
    簡書CCL閱讀 915評論 0 1

友情鏈接更多精彩內(nèi)容