溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python中字符串駐留的機(jī)制是什么

發(fā)布時(shí)間:2023-05-09 14:44:42 來(lái)源:億速云 閱讀:320 作者:zzz 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“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

1 什么是字符串駐留機(jī)制

字符串駐留機(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)存的情況下使用相同的字符串。

2 如何使用字符串駐留機(jī)制

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”。

3 簡(jiǎn)單拼接駐留, 運(yùn)行時(shí)不駐留

我們來(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ě)成拼接的形式都是一樣的。

4 總結(jié)

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)題。

5 全部代碼

上面已經(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í)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI