听说92.8%的人答不对这道Python题,我不信,后来我信了!真有趣
每種編程語言都有一些不為人知的陷阱,有些實際工作中會踩到,有些可能根本排不上用場,但弄明白這些陷阱有利于我們更好的去了解這門語言的實現(xiàn)機制。
下面這個題,你是否能一眼看出問題的本質(zhì)。
不管是 Python2 還是 Python3 環(huán)境下,只要你是在 CPython 的交互式命令行 REPL 中執(zhí)行,結(jié)果沒什么不同。
我們知道 is 比較的是兩個對象的內(nèi)存地址是否一樣( id 函數(shù)返回一個和對象的內(nèi)存地址相關(guān)的值),言外之意就是看a,b兩個變量是否指向同一個對象。我們來看看每個變量的 id 值。
不出所料,前后兩組 a,b的 id 值是相同的,只有中間這組 id 值不一樣,我們可以對其簡單分析一下原因。在 Python 中,一切皆為對象,理論上任意兩個對象的 id 值都是不一樣的!
例如:
嗨嘍:小編是一名python開發(fā)工程師,這里有我自己整理了一套最新的python系統(tǒng)學(xué)習(xí)教程, 包括從基礎(chǔ)的python腳本到web開發(fā)、爬蟲、數(shù)據(jù)分析、數(shù)據(jù)可視化、機器學(xué)習(xí)等。想要的加Q裙:895817687>>> nums = [1,2,3,4] >>> id(nums) 15148936 >>> nums2 = [1,2,3] >>> id(nums2) 15160824 >>> nums3 = [1,2,3] >>> id(nums3) 15160864看得出每個對象的 id 值是不同的,哪怕兩個對象的值(內(nèi)容)相同,他們的 id 值也是不一樣的(nums2和nums3)。那為什么前面第一組兩個對象的id值相同呢?可能有些同學(xué)已經(jīng)知道了
因為在 Python 中,我們需要使用對象的時候 Python 就會為我們創(chuàng)建好,當(dāng)不需要了它就會進行回收,就好比屋子里面的東西用完之后,要及時清理,否則整個屋子很快就會堆滿,最終導(dǎo)致房間再也塞不進任何東西。
同樣的,為了提高性能,Python 就把一些常用的整數(shù)專門緩存起來,就像屋子里面有些東西總是每天都要頻繁使用,比如床,你不能說睡完之后,就把床搬出去,要用了再搬回來,這樣的效率太低,因為這個搬運過程實在是太耗時了。于是,我們可以專門拿一塊空間用來放置這個床。
Python 中也是同樣的道理,因為整數(shù)是我們經(jīng)常使用的對象,為了避免重復(fù)的創(chuàng)建、回收,干脆就把那些常用的整數(shù)緩存起來,每次需要使用時直接從緩存中拿,而不是重新創(chuàng)建(重新創(chuàng)建的話,肯定是一個全新的對象)。這些整數(shù)的范圍是[-5, 256],當(dāng)然這個數(shù)字范圍是Python之父決定的,你要改,必須重新編譯Python環(huán)境。
現(xiàn)在我們就能解釋第一組為什么是True,第二組為什么是False了。為什么第三組結(jié)果又是 True 了?,不是說好大于256的整數(shù)不再緩存,每次使用都是新對象嗎?別急,再聽我啰嗦一下。
還是出于性能考慮,Python內(nèi)部做了進一步優(yōu)化,怎么優(yōu)化呢?但凡是在同一個代碼塊中的代碼,如果出現(xiàn)兩個值相同的整數(shù),那么它們將被重用,來看下面這個代碼:
嗨嘍:小編是一名python開發(fā)工程師,這里有我自己整理了一套最新的python系統(tǒng)學(xué)習(xí)教程, 包括從基礎(chǔ)的python腳本到web開發(fā)、爬蟲、數(shù)據(jù)分析、數(shù)據(jù)可視化、機器學(xué)習(xí)等。想要的加Q裙:895817687# test.py # -*- coding: utf-8 -*- a = 257 b = 257 def func():c = 257print(a is c) # False print(a is b) # True func()上面代碼是在一個 test.py 文件中,運行時,a和b的id值相同,而c的id值與a不一樣,因為a、b 在同一個代碼塊,屬于模塊級別,而 c 是在函數(shù)里面,屬于局部變量,他們不屬于同一代碼塊中,因此函數(shù)里面的 257 這個對象時會重新創(chuàng)建,而創(chuàng)建 b 的時候,發(fā)現(xiàn)同級代碼塊中有個257的值了,就重用了這個對象。
再回到前面講的第三組值,在 Python 的交互式命令行 REPL 中,每單獨一行都視為一個代碼塊,同一行中的代碼屬于同一個代碼塊,因此不難理解,第三組中的a和b處在同一個代碼塊中,所以后者重用了前者,因此,兩個變量的id是相同的。
有沒有覺得這是一個坑。雖然我們實際場景中并不一定能用上,但是至少我們知道了Python為我們做的一些優(yōu)化工作。
總結(jié)
以上是生活随笔為你收集整理的听说92.8%的人答不对这道Python题,我不信,后来我信了!真有趣的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 123456789怎样运算等于1?答案可
- 下一篇: Python中from import和i