您好,登錄后才能下訂單哦!
本篇內容主要講解“Python整數問題怎么理解”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Python整數問題怎么理解”吧!
在 Python 中一切都是對象,毫無例外整數也是對象,對象之間比較是否相等可以用==,也可以用is。==和is操作的區別是:
is比較的是兩個對象的id值是否相等,也就是比較倆對象是否為同一個實例對象,是否指向同一個內存地址。
==比較的是兩個對象的內容是否相等,默認會調用對象的__eq__()方法。
清楚is和==的區別之后,對此也許你有可能會遇到下面的這些困惑,我們先來看兩段代碼:
片段一:
>>> a = 256 >>> b = 256 >>> a == b True >>>
片段二:
>>> a = 256 >>> b = 256 >>> a is b True >>>
在交互式命令行執行上面兩段代碼,代碼片段一中的a==b返回True很好理解,因為兩個對象的值都是256,對于片段二,a is b也返回True,這說明a和b是指向同一個對象的,可以檢查一下他們的id值是否相等:
>>> id(a) 8213296 >>> id(b) 8213296 >>>
結果證明他倆的確是同一個對象,指向的是同一個內存地址。那是不是所有的整數對象只要兩個對象的值(內容)相等,它們就是同一個實例對象呢?換句話說,對于整數對象只要==返回True,is操作也會返回True嗎?帶著這個問題來看下面這兩段代碼:
片段一:
>>> a = 257 >>> b = 257 >>> a == b True >>>
片段二:
>>> a = 257 >>> b = 257 >>> a is b False >>>
對于257,a is b返回的竟然是False,結果可能在你的意料之中,也有可能出乎你的意料,但不管怎么,我們還是要刨根問底,找出問題的真相。
解惑一
出于對性能的考慮,Python內部做了很多的優化工作,對于整數對象,Python把一些頻繁使用的整數對象緩存起來,保存到一個叫small_ints的鏈表中,在Python的整個生命周期內,任何需要引用這些整數對象的地方,都不再重新創建新的對象,而是直接引用緩存中的對象。Python把這些可能頻繁使用的整數對象規定在范圍[-5, 256]之間的小對象放在small_ints中,但凡是需要用些小整數時,就從這里面取,不再去臨時創建新的對象。因為257不再小整數范圍內,因此盡管a和b的值是一樣,但是他們在Python內部卻是以兩個獨立的對象存在的,各自為政,互不干涉。
弄明白***個問題后,我們繼續在Python交互式命令行中寫一個函數,再來看下面這段代碼:
片段一:
>>> c = 257 >>> def foo(): ... a = 257 ... b = 257 ... print a is b ... print a is c ... >>> foo() True False
呃,什么情況,是的,你沒看錯,片段一中的這段代碼 a、b 值都是257的情況下,出現了a is b返回True,而a is c 返回的False,a、b、c的值都為257,為什么會出現不同的結果呢?這對于剛剛好不容易建立起來的認知就被徹底否決了嗎,那這段代碼中究竟發生了什么?難道解惑一中的結論是錯誤的嗎?
解惑二
為了弄清楚這個問題,我們有必要先理解程序代碼塊的概念。Python程序由代碼塊構成,代碼塊作為程序的一個最小基本單位來執行。一個模塊文件、一個函數體、一個類、交互式命令中的單行代碼都叫做一個代碼塊。在上面這段代碼中,由兩個代碼塊構成,c = 257作為一個代碼塊,函數foo作為另外一個代碼塊。Python內部為了將性能進一步的提高,凡是在一個代碼塊中創建的整數對象,如果存在一個值與其相同的對象于該代碼塊中了,那么就直接引用,否則創建一個新的對象出來。Python出于對性能的考慮,但凡是不可變對象,在同一個代碼塊中的對象,只有是值相同的對象,就不會重復創建,而是直接引用已經存在的對象。因此,不僅是整數對象,還有字符串對象也遵循同樣的原則。所以 a is b就理所當然的返回True了,而c和a不在同一個代碼塊中,因此在Python內部創建了兩個值都是257的對象。為了驗證剛剛的結論,我們可以借用dis模塊從字節碼的角度來看看這段代碼。
>>> 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
可以看出兩個257都是從常量池的同一個位置co_consts[1]獲取的。
到此,相信大家對“Python整數問題怎么理解”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。