您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python中字符串駐留的機(jī)制是什么”,在日常操作中,相信很多人在Python中字符串駐留的機(jī)制是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”P(pán)ython中字符串駐留的機(jī)制是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
看以下代碼:
a = [1, 2, 3] b = [1, 2, 3] if a is b: print("a and b point to the same object") else: print("a and b point to different objects")
運(yùn)行結(jié)果是a and b point to different objects。
然后他又試了字符串對(duì)象。
str1 = "hello" str2 = "hello" if str1 is str2: print("str1 and str2 are the same object") else: print("str1 and str2 are different objects")
運(yùn)行結(jié)果是:str1 and str2 are the same object
字符串駐留機(jī)制是Python針對(duì)字符串對(duì)象采取的一種內(nèi)存優(yōu)化技術(shù)。其目標(biāo)是減少內(nèi)存使用并提高程序的性能。
在Python中,字符串是不可變的對(duì)象,一旦創(chuàng)建,就不能被修改。因此,如果我們創(chuàng)建了兩個(gè)字符串,它們將占用兩個(gè)不同的內(nèi)存位置。但是,如果這些字符串是相同的,那么它們將被Python自動(dòng)合并為一個(gè)對(duì)象,這就是字符串駐留機(jī)制。
Python中的字符串駐留機(jī)制是通過(guò)使用intern機(jī)制來(lái)實(shí)現(xiàn)的。當(dāng)我們創(chuàng)建一個(gè)字符串時(shí),Python會(huì)檢查字符串池中是否已經(jīng)存在相同的字符串。如果是,它將返回現(xiàn)有的字符串對(duì)象的引用,而不是創(chuàng)建一個(gè)新的對(duì)象。這樣,我們可以在不占用額外內(nèi)存的情況下使用相同的字符串。
Python的字符串駐留機(jī)制在不同版本之間有一些變化。下面是一些主要的變化:
1.Python 2.x和Python 3.x的字符串駐留機(jī)制不同。在Python 2.x中,只有長(zhǎng)度為1的字符串才會(huì)被駐留。而在Python 3.x中,長(zhǎng)度為0到20的字符串都會(huì)被駐留。 (更長(zhǎng)的田辛老師試過(guò),似乎都可以)
2.在Python 3.7之前,字符串駐留機(jī)制只適用于ASCII字符集中的字符串。這意味著只有ASCII字符集中的字符串才會(huì)被駐留。但是,在Python 3.7中,這個(gè)限制已經(jīng)被取消,所有字符串都可以被駐留。
3.在Python 3.8中,字符串駐留機(jī)制的實(shí)現(xiàn)發(fā)生了變化。在之前的版本中,字符串池是一個(gè)全局的數(shù)據(jù)結(jié)構(gòu),所有的字符串都存儲(chǔ)在其中。但是,在Python 3.8中,字符串池被改為了一個(gè)線程局部的數(shù)據(jù)結(jié)構(gòu),每個(gè)線程都有自己的字符串池。這樣可以提高多線程程序的性能。
需要注意的是,字符串駐留機(jī)制是Python的一種優(yōu)化技術(shù),它并不是Python語(yǔ)言規(guī)范的一部分。因此,不同的Python實(shí)現(xiàn)(如CPython、Jython、IronPython等)可能會(huì)有不同的字符串駐留機(jī)制實(shí)現(xiàn)。
正是因?yàn)樯厦娴淖兓?所以有的時(shí)候田辛老師覺(jué)得字符串駐留在面向內(nèi)存的時(shí)候是友好的, 但確實(shí)會(huì)給新手帶來(lái)一些不便。
作為新手, 田辛老師提供一個(gè)手動(dòng)使用字符串駐留的例子:
import sys # 使用sys.intern()函數(shù)啟用字符串駐留機(jī)制 str3 = sys.intern("hello") str4 = sys.intern("hello") # 使用is關(guān)鍵字比較兩個(gè)字符串是否相同 if str3 is str4: print("str3 and str4 are the same object") else: print("str3 and str4 are different objects")
上面的例子中,田辛老師使用sys.intern()函數(shù)將字符串“hello”添加到字符串池中,并將返回的引用分配給str3和str4。然后,我們?cè)俅问褂胕s關(guān)鍵字比較它們是否相同。由于它們是相同的對(duì)象,因此輸出結(jié)果為“str3 and str4 are the same object”。
我們來(lái)看下面的代碼:
str5 = 'tianxin' + 'training' print(str5 is 'tianxintraining') str6 = 'tianxin' str7 = 'training' print((str6 + str7) is 'tianxintraining')
大家可以猜一猜輸出結(jié)果是什么? 是兩個(gè)true,還是一個(gè)true一個(gè)false?
答案是:
True
False
為什么會(huì)出現(xiàn)這種情況呢? 第一個(gè)打印,是兩個(gè)字符串簡(jiǎn)單拼接, 那么就會(huì)實(shí)現(xiàn)字符串駐留。 但是, 一旦是變量拼接字符串機(jī)制就不能用了。
關(guān)于這一點(diǎn), 田辛老師通過(guò)如下代碼帶領(lǐng)大家查看一下上述兩個(gè)處理的匯編執(zhí)行過(guò)程:
import dis def pro1(): str5 = 'tianxin' + 'training' print(str5 is 'tianxintraining') def pro2(): str6 = 'tianxin' str7 = 'training' print((str6 + str7) is 'tianxintraining') print('================================================================') dis.dis(pro1) print('================================================================') dis.dis(pro2)
輸出結(jié)果:
================================================================
20 0 LOAD_CONST 1 ('tianxintraining')
2 STORE_FAST 0 (str5)
21 4 LOAD_GLOBAL 0 (print)
6 LOAD_FAST 0 (str5)
8 LOAD_CONST 1 ('tianxintraining')
10 IS_OP 0
12 CALL_FUNCTION 1
14 POP_TOP
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
================================================================
25 0 LOAD_CONST 1 ('tianxin')
2 STORE_FAST 0 (str6)
26 4 LOAD_CONST 2 ('training')
6 STORE_FAST 1 (str7)
27 8 LOAD_GLOBAL 0 (print)
10 LOAD_FAST 0 (str6)
12 LOAD_FAST 1 (str7)
14 BINARY_ADD
16 LOAD_CONST 3 ('tianxintraining')
18 IS_OP 0
20 CALL_FUNCTION 1
22 POP_TOP
24 LOAD_CONST 0 (None)
26 RETURN_VALUE
進(jìn)程已結(jié)束,退出代碼0
我們可以看到, Python的解釋器對(duì)這種簡(jiǎn)單的字符串拼接在形成字符碼的時(shí)候,就已經(jīng)進(jìn)行了拼接。 str5 你寫(xiě)不寫(xiě)成拼接的形式都是一樣的。
Python的字符串駐留機(jī)制是一種優(yōu)化技術(shù),它可以減少內(nèi)存使用并提高程序的性能。它的做法的基礎(chǔ)是Python字符串對(duì)象的不可改變的特性。 當(dāng)然, 不同的Python版本對(duì)于字符串駐留機(jī)制的處理不同可能會(huì)給初學(xué)者帶來(lái)一些麻煩。 Python學(xué)習(xí)者必須要面對(duì)的一個(gè)問(wèn)題。
上面已經(jīng)有了關(guān)于輸出匯編的全部代碼, 就不再重新輸出了。 只展示字符串駐留部分的代碼:
#!/usr/bin/env python # -*- coding:utf-8 -*- """ #----------------------------------------------------------------------------- # --- TDOUYA STUDIOS --- #----------------------------------------------------------------------------- # # @Project : di08-tdd-cdg-python-learning # @File : str_intern.py # @Author : tianxin.xp@gmail.com # @Date : 2023/4/5 10:34 # # 代碼說(shuō)明 # #--------------------------------------------------------------------------""" import sys a = [1, 2, 3] b = [1, 2, 3] if a is b: print("a and b point to the same object") else: print("a and b point to different objects") str1 = "hello" str2 = "hello" if str1 is str2: print("str1 and str2 are the same object") else: print("str1 and str2 are different objects") # 使用sys.intern()函數(shù)啟用字符串駐留機(jī)制 str3 = sys.intern("hello") str4 = sys.intern("hello") # 使用is關(guān)鍵字比較兩個(gè)字符串是否相同 if str3 is str4: print("str3 and str4 are the same object") else: print("str3 and str4 are different objects") str5 = 'tianxin' + 'training' print(str5 is 'tianxintraining') str6 = 'tianxin' str7 = 'training' print((str6 + str7) is 'tianxintraining')
執(zhí)行結(jié)果:警告可忽略
D:\python-grp\miniconda_env\py3.10\python.exe E:\develop\python\di08-tdd-cdg-python-learning\src\std_str_intern\str_intern.py
a and b point to different objects
str1 and str2 are the same object
str3 and str4 are the same object
True
False
E:\develop\python\di08-tdd-cdg-python-learning\src\std_str_intern\str_intern.py:44: SyntaxWarning: "is" with a literal. Did you mean "=="?
print(str5 is 'tianxintraining')
E:\develop\python\di08-tdd-cdg-python-learning\src\std_str_intern\str_intern.py:48: SyntaxWarning: "is" with a literal. Did you mean "=="?
print((str6 + str7) is 'tianxintraining')
進(jìn)程已結(jié)束,退出代碼0
到此,關(guān)于“Python中字符串駐留的機(jī)制是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。