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