日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python字符串常量有什么区别_Python经典面试题:is与==的区别

發布時間:2025/3/11 python 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python字符串常量有什么区别_Python经典面试题:is与==的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

is用于判斷兩個對象是否為同一個對象,具體來說是兩個對象在內存中的位置是否相同。

python為了提高效率,節省內存,在實現上大量使用了緩沖池技術和字符串intern技術。

整數和字符串是不可變對象,也就意味著可以用來共享,如100個“python”字串變量可以共享一個“python”字符串對象,而不是創建100個“python”字符串。

一、小整數對象池

為了應對小整數的頻繁使用,python使用對小整數進行了緩存,默認范圍為[-5,256],在這個范圍內的所有整數被python完全地緩存,當有變量使用這些小整數時,增加對應小整數對象的引用即可。

由上面的實例可以看到,當變量在[-5,256]之間時,兩個值相同的變量事實上會引用到同一個小整數對象上,也就是小整數對象池中的對象,而不會去創建兩個對象。而當變量超出了這個范圍,兩個值相同的變量也會各自創建整數對象,所以兩者對應的對象不同。

二、字符串intern

如果當前變量引用的字符串對象已經存在的話,直接增加對應字符串對象的引用,而不去創建新的字符串對象,這就是字符串intern機制。

說白了,intern機制就是每創建一個比較短的字符串對象,就在一個叫interned的字典里面查看是否存在字符串相同的字符串對象,如果存在的話,就把字典存放的對象的ob_refcnt加1,然后銷毀新創建的對象,所以才會出現下面的情景?a is b的結果為True:

1. 奇怪的現象

在詳細探討字符串intern機制之前,先看一個奇怪的問題:

直接在交互式IPython中運行:

i is j的結果是False。

定義一個函數并運行:

輸出結果:

True

上述代碼分開運行,結果為False,但是合在一起結果卻為True。也就是說分開運行的時候,i和j指向不同對象,而合在一起的時候i,j卻指向了相同對象。為了明白其中的緣由,需要簡單理解python的編譯機制。

三、編譯機制

在python中,萬物皆對象,包括代碼本身也是一種對象。python用code對象表示代碼,代碼編譯后產生code對象。通常一個作用域對應一個code對象。

1. 編譯結果

上述代碼中編譯生成了兩個code對象,一個代表全局作用域,另一個代表函數f。

code對象保存了變量,常量(常量字面量)以及編譯結果。code對象用常量表來保存常量,考慮到一個常量可能出現多次,在一張表上保存一個常量多次太過于奢侈。所以code對象對每個常量只保存一次,在需要引用它的地方使用它在常量表的位置作為常量的表示。在上述編譯結果中可以看到,"1 2"這個字符串常量使用了兩次,編譯的代碼為"LOAD_CONST 0",這里的0就是"1 2"在常量表當中的位置。

由于編譯的這個特性,在同一個code對象 中的變量,如果它們引用了同一個常量,那么無論這個常量有沒有緩沖機制,它們引用的都是同一個對象。

2. 案例理解

輸出結果:

True True True True

字符串對象除了intern機制以外,還有類似于小整數對象的字符緩沖池,其實就是用一個類似于數組的東西(characters array)指向這個對象,對只有一個字符的字符串,第一次創建時候會進行如下操作:

1.創建對象

2.對其進行intern操作

3.將對象放進字符緩沖池

那么下次再創建這個字符對象時候,會首先查看字符緩沖池中是否存在這個對象,如果存在的話,返回這個緩沖對象。區別于小整數對象的是,小整數對象在python解釋器初始化之初就創建了,而字符串緩沖池指向的對象直到用到的時候才會創建。

四、編譯機制與小整數對象池對比

i和j引用同一個常量,這是編譯機制,所以i與j指向同一個整數對象,后面a和b雖然相等,但不引用常量,此時啟用小整數對象池,a和b都等于256,在對象池中,所以a,b引用同一個對象,后面c和d不在對象池中,所以兩者對象不同。

這里有一點需要注意,沒有變量參與的運算會被編譯器直接優化成對應的常量,進而保存進常量表中。

五、字符串intern機制與字符緩沖池

在編譯過程中,字符串intern機制將所有的變量名進行intern,但對常量進行的intern有一點特殊的限制。能夠intern的常量必須只包含[a-zA-Z0-9_],即字母數字加下劃線,如果含有其他字符,就不會intern。在運行過程中,通過計算得到的字符串不會intern。

字符串有一個和小整數對象池相似的字符緩沖池,用于在運行過程中緩存單個字符,所以計算得到的字符串雖然不會intern,但如果是單個字符,就會使用到字符緩沖池。

可以看到,a和b確實指向同一個對象,而c和d指向不同對象,這就是字符緩沖池。

六、編譯機制與字符串intern對比

i包含空格,包含空格的常量不會被intern,而其他兩個常量不包含其他字符,所以會被intern。

七、總結python代碼被編譯成code對象,通常一個code對象對應于一個作用域,作用域中重復出現的變量名以及常量在code中只保存一次。

字符串intern機制主要作用于編譯過程,在編譯收集完變量和常量時,對變量和常量進行intern,而后構建一個code對象。

字符串intern對常量的intern有限制,能夠intern的常量必須只包含[a-zA-Z0-9_],即字母數字加下劃線,如果含有其他字符,就不會intern。

小整數對象池和字符緩沖池都是作用于運行過程中,python緩存小的整數和字符,當有變量使用這些對象時,不用額外創建對象。

總結

以上是生活随笔為你收集整理的python字符串常量有什么区别_Python经典面试题:is与==的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。