python中id函数的用法_用id函数做几个测试
Python內(nèi)置的id函數(shù)其實(shí)非常簡(jiǎn)單,就是將參數(shù)對(duì)象的內(nèi)存地址返回,即id函數(shù)返回的是一個(gè)很大的整數(shù)(地址)。基于Python語言的特性,本文做了幾個(gè)測(cè)試,還比較有趣。
相同整數(shù)的id相同
>>> a = 6
>>> b = 6
>>> id(a)
94061989787808
>>> id(b)
94061989787808
>>> a == b
True
>>> a is b
True
a和b是兩個(gè)變量,但是按照上面代碼的顯示,a和b不僅內(nèi)容相同,地址也相同,a就是b。(==和is的區(qū)別)
這是Python為了高效利用內(nèi)存而采取的一種機(jī)制,a和b都是對(duì)一個(gè)內(nèi)存中對(duì)象的引用,賦值(=)實(shí)際上是創(chuàng)建一個(gè)對(duì)象,將地址給引用變量。既然a和b指向的對(duì)象都是6這個(gè)整數(shù),Python就沒有“動(dòng)力”去創(chuàng)建多個(gè)對(duì)象了。有人會(huì)問,如果修改變來領(lǐng)的值,比如修改a的值為7,b的值會(huì)跟著變嗎?答案是不會(huì)。看下面的代碼:
>>> a = 7
>>> a
7
>>> b
6
>>> id(a)
94061989787840
>>> id(b)
94061989787808
>>> a == b
False
>>> a is b
False
當(dāng) a=7 時(shí),Python實(shí)際上是創(chuàng)建了一個(gè)新的值為7的整數(shù)對(duì)象,讓a引用,同時(shí)保持6這個(gè)整數(shù)對(duì)象不變,這時(shí),a和b的指向地址就不再相同了。
這是Python跟C很不一樣的一個(gè)地方。在Python中,一切都是對(duì)象,所有變量都是對(duì)某個(gè)對(duì)象的應(yīng)用(有點(diǎn)像指針),內(nèi)存管理自動(dòng)進(jìn)行(某個(gè)對(duì)象的引用數(shù)為0的時(shí)候,自動(dòng)清理這部分內(nèi)存)。在C中,一切都是內(nèi)存和指針,C編碼在某種意義上是面向內(nèi)存的編碼,任何變量以及函數(shù)的返回值,都要明確定義類型,類型就是占用內(nèi)存的大小。
相同整數(shù)的id不同
>>> i1 = 666666
>>> i2 = 666666
>>> i1 == i2
True
>>> i1 is i2
False
>>> id(i1)
140693768352752
>>> id(i2)
140693768353040
如果兩個(gè)整數(shù)值比較大,id就不一樣了。我也不明白為什么?數(shù)值小,id一樣,數(shù)值大,id不一樣。
相同浮點(diǎn)數(shù)的id不同
貌似浮點(diǎn)數(shù),id總是不同的,這應(yīng)該與浮點(diǎn)數(shù)的比較有關(guān)系(不能直接用==來比較浮點(diǎn)數(shù))。
>>> f1 = 1.23
>>> f2 = 1.23
>>> f1 is f2
False
>>> f1 == f2 # not right to compare like this
True
>>> id(f1)
140693769437496
>>> id(f2)
140693769437304
返回函數(shù)局部變量
如上文所述,Python中所有的變量都是像C語言的指針一樣,是一個(gè)指向?qū)ο蟮囊?#xff0c;Python在返回函數(shù)的局部變量的時(shí)候,返回的也是這個(gè)局部變量的引用地址。
>>> def test():
... a = 12345
... print(id(a))
... return a
...
>>> b = test()
140693768353008 # id(a) in test()
>>> id(b)
140693768353008
test函數(shù)執(zhí)行完畢后,將a的內(nèi)存地址返回給了b。
這一個(gè)細(xì)節(jié)在一開始,還困擾了我一小會(huì)兒。函數(shù)的局部變量的地址處于調(diào)用棧內(nèi),在函數(shù)執(zhí)行完成后,調(diào)用棧就會(huì)被彈出,局部變量的地址就失效了,不能在引用了。為什么Python不是這樣呢?
Python確實(shí)沒有為b重新創(chuàng)建一個(gè)新的對(duì)象,a對(duì)象對(duì)應(yīng)的地址被傳給了b,但是a這個(gè)變量也隨著test函數(shù)執(zhí)行完畢而消失了(a被彈出了調(diào)用棧,而不是a指向的內(nèi)存對(duì)象被彈出,這段內(nèi)存可理解在heap中)。Python中的變量,像指針,但卻不是指針,只是對(duì)象的引用。a的有效范圍在test函數(shù)內(nèi),test函數(shù)執(zhí)行完后,a就不復(fù)存在,b獲取了test函數(shù)的“返回值”,我們沒有必要糾結(jié)b的內(nèi)存地址是否與局部變量a一樣。Python自己管理內(nèi)存,我們編程者不需要太關(guān)心。a不能再使用了,但是a指向的內(nèi)存對(duì)象還可以繼續(xù)被使用,這并沒有違背函數(shù)調(diào)用棧的邏輯(a本身被彈出棧,a指向的內(nèi)存對(duì)象還在別的地方存在著,只要還有引用)。
Python內(nèi)置的id函數(shù)一般情況下,沒有什么用于,主要用于調(diào)試等場(chǎng)景。
-- EOF --
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的python中id函数的用法_用id函数做几个测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 微信群发多图文_[Java教程
- 下一篇: python elif可以单独使用_Py