python字符串常量有什么區別_Python經典面試題:is與==的區別

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

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

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

一、小整數對象池

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

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

二、字符串intern

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

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

1. 奇怪的現象

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

直接在交互式IPython中運行:3ef974842236bc90e5dafbf8277bbb5a.png

i is j的結果是False。

定義一個函數并運行:b279260cd4cf77700f6e1d4acb23b53c.png

輸出結果:

True

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

三、編譯機制

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

1. 編譯結果42004da23ab6013c5d94918df039401e.png

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

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

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

2. 案例理解99d9e32e4f6c8976a12b0d28f34a0c2d.png

輸出結果:

True True True True

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

1.創建對象

2.對其進行intern操作

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

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

四、編譯機制與小整數對象池對比2bce5a560a00bc72e825b9bbe7f49b1f.png

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,但如果是單個字符,就會使用到字符緩沖池。78038ab3595d390ed6483e3b1a7934df.png

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

1dd34ce6bfa6a1b19e5c13cde1975244.png

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

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

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

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

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

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539685.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539685.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539685.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

left join、right join、inner join的區別

left join(左聯接) 返回包括左表中的所有記錄和右表中聯結字段相等的記錄 right join(右聯接) 返回包括右表中的所有記錄和左表中聯結字段相等的記錄 inner join(等值連接) 只返回兩個表中聯結字段相等的行 舉例如下: ----------------------------------------…

Javascript Proxy對象 簡介

Javascript Proxy對象 簡介 本文轉載自:眾成翻譯 譯者:eJayYoung 鏈接:http://www.zcfy.cc/article/4755 原文:https://blog.campvanilla.com/advanced-guide-javascript-proxy-objects-introduction-301c0fce9432 Javascript …

App架構經驗總結

原文地址:http://www.iteye.com/news/31472-------------------------------------------------------------架構因人而異,不同的架構師大多會有不同的看法;架構也因項目而異,不同的項目需求不同,相應的架構也會不同。…

python數字排序 循環_【python-leetcode448-循環排序】找到所有數組中消失的數字

問題描述:給定一個范圍在 1 ≤ a[i] ≤ n ( n 數組大小 ) 的 整型數組,數組中的元素一些出現了兩次,另一些只出現一次。找到所有在 [1, n] 范圍之間沒有出現在數組中的數字。您能在不使用額外空間且時間復雜度為O(n)的情況下完成這個任務嗎…

saiku+kettle整合(六)olap操作

title: saikukettle整合(六)olap操作 tags: categories: saiku date: 2016-08-25 18:18:54 使用saiku可以對應使用相關olap操作 OLAP的基本操作 我們已經知道OLAP的操作是以查詢——也就是數據庫的SELECT操作為主,但是查詢可以很復雜&#xf…

攜程Docker實踐

原文地址:http://www.iteye.com/news/31468 請點擊原文閱讀 ---------------------以下是原文---------------------- 從去年底開始,攜程開始計劃把Docker引入到攜程的云平臺,這是系統研發部一部分的工作任務,攜程系統研…

mysql全文索引thinkphp_ThinkPHP5 使用迅搜 (XunSearch) 實現全文檢索實例指導

前期準備入坑了一天,折騰的無語,個人觀點:【文檔太差,適合學習思路,不建議入坑】背景最近在整理全文檢索解決方案注意到 xunsearch 的評價很高,在此記錄一番場景描述此處作為對 xunsearch 的初次使用&#…

為何有些程序員總是想要“干掉”產品經理?

好了,我準備去和產品經理做斗爭去了,請祝我好運吧!小編花了大量時間收集了很多干貨編程學習資源,其中資源包括 算法,大數據,人工智能,Python,Android,iOS,Jav…

多個left join 產生多個結果

select a.*,to_char(To_date(20160403000000, yyyyMMddhh24miss),yyyy/mm/dd) as omc_start_time,to_char(To_date(20160404000000, yyyyMMddhh24miss),yyyy/mm/dd) as omc_end_time,ROUND(sc."切換成功率",2) AS "OMC-源小區切換成功率%",ROUND(sc."…

查看進程占用,并kill掉

今天發現8899端口被占,服務器啟動失敗,用了下面的命令解決。 [rootltesqm Toolbox]# netstat -tunlp |grep 8899 tcp 0 0 :::8899 :::* LISTEN 28279/java [rootltesqm Toolbox]…

Spark算子篇 --Spark算子之combineByKey詳解

一。概念 rdd.combineByKey(lambda x:"%d_" %x, lambda a,b:"%s%s" %(a,b), lambda a,b:"%s$%s" %(a,b))三個參數(都是函數)第一個參數:給定一個初始值,用函數生成初始值。第二個參數:c…

mysql proxy 主從_【MYSQL知識必知必會】MySQL主從復制讀寫分離(基于mysql-proxy實現)...

MySQL主從復制讀寫分離(基于mysql-proxy實現)http://mirror.bit.edu.cn/mysql/Downloads/MySQL-Proxy/mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz解壓tar zxvf mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz創建mysql-proxy帳號并授權分別在主從數據庫中創建mys…

SecureCRT防止自動斷開

今天在寧波連接上海的linux庫,是外網訪問內網,使用了nat123這個軟件映射的。 發現SecureCRT連接后,過幾分鐘就自動斷開,導致使用SecureCRT做跳轉機的其他應用使用起來很不方便。 于是設置了下SecureCRT。

mysql 主主結構_高性能mysql主主架構

(3)配置參數說明server-id:ID值唯一的標識了復制群集中的主從服務器,因此它們必須各不相同。master_id必須為1到232–1之間的一個正整數值,slave_id值必須為2到232–1之間的一個正整數值。log-bin:表示打開binlog,打開該選項才可以…

解決ios編譯swift報錯pcm was built: mtime changed

問題 編譯ios工程失敗時,其中的幾個swift文件報以下錯 /Users/tomes/code/project/xxx.swift File /Users/tomes/Library/Developer/Xcode/DerivedData/Spec-dgyhrnmgvfkjkqbboklnfgrudqip/Build/Products/Debug-iphoneos/xxxx.framework/Headers/xxxx.h has been…

AI工程師職業規劃和學習路線完整版

AI工程師職業規劃和學習路線完整版 如何成為一名機器學習算法工程師 成為一名合格的開發工程師不是一件簡單的事情,需要掌握從開發到調試到優化等一系列能 力,這些能力中的每一項掌握起來都需要足夠的努力和經驗。而要成為一名合格的機器學習算法工程師&…

oracle 多個with as

主要看多個with的格式 [sql] view plaincopy WITH T3 AS ( SELECT T1.ID, T1.CODE1, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.CODE1 T2.CODE ), T4 AS ( SELECT T1.ID, T1.CODE2, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.C…

mysql主鍵 命中率_mysql主鍵問題

MySQL主鍵一. MySQL主鍵設計原則MySQL主鍵應當是對用戶沒有意義的。MySQL主鍵應該是單列的,以便提高連接和篩選操作的效率(當然復合主鍵是可以的,只是不建議)永遠也不要更新MySQL主鍵MySQL主鍵不應包含動態變化的數據,如時間戳、創建時間列、…

Centos7常用命令[掛載文件系統]

Centos7常用命令[掛載文件系統]------------------------------------------------------------------------------# 掛載一個叫做hda2的盤-確定目錄/mnt/hda2已經存在[rootlocalhost ~]# mount /dev/hda2 /mnt/hda2# 卸載一個叫做hda2的盤-先從掛載點/mnt/hda2退出[rootlocalh…

hadoop SecondNamenode

一、定義 * The Secondary Namenode is a helper to the primary Namenode. * The Secondary is responsible for supporting periodic checkpoints * of the HDFS metadata. The current design allows only one Secondary * Namenode per HDFs cluster. * The Secondary Nam…