最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python小整數(shù)對(duì)象池和字符串intern實(shí)例解析

 更新時(shí)間:2020年03月21日 12:32:33   作者:luoheng  
這篇文章主要介紹了Python小整數(shù)對(duì)象池和字符串intern實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

is用于判斷兩個(gè)對(duì)象是否為同一個(gè)對(duì)象,具體來(lái)說(shuō)是兩個(gè)對(duì)象在內(nèi)存中的位置是否相同。

python為了提高效率,節(jié)省內(nèi)存,在實(shí)現(xiàn)上大量使用了緩沖池技術(shù)和字符串intern技術(shù)。

整數(shù)和字符串是不可變對(duì)象,也就意味著可以用來(lái)共享,如100個(gè)“python”字串變量可以共享一個(gè)“python”字符串對(duì)象,而不是創(chuàng)建100個(gè)“python”字符串。

小整數(shù)對(duì)象池

為了應(yīng)對(duì)小整數(shù)的頻繁使用,python使用對(duì)小整數(shù)進(jìn)行了緩存,默認(rèn)范圍為[-5,256],在這個(gè)范圍內(nèi)的所有整數(shù)被python完全地緩存,當(dāng)有變量使用這些小整數(shù)時(shí),增加對(duì)應(yīng)小整數(shù)對(duì)象的引用即可。

>>> i = -5
>>> j = -5
>>> i is j # i和j是同一個(gè)對(duì)象
True
>>> i = 256
>>> j = 256
>>> i is j # i和j是同一個(gè)對(duì)象
True
>>> i = 257
>>> j = 257
>>> i is j # i和j是不同對(duì)象
False

由上面的實(shí)例可以看到,當(dāng)變量在[-5,256]之間時(shí),兩個(gè)值相同的變量事實(shí)上會(huì)引用到同一個(gè)小整數(shù)對(duì)象上,也就是小整數(shù)對(duì)象池中的對(duì)象,而不會(huì)去創(chuàng)建兩個(gè)對(duì)象。而當(dāng)變量超出了這個(gè)范圍,兩個(gè)值相同的變量也會(huì)各自創(chuàng)建整數(shù)對(duì)象,所以兩者對(duì)應(yīng)的對(duì)象不同。

字符串intern

如果當(dāng)前變量引用的字符串對(duì)象已經(jīng)存在的話,直接增加對(duì)應(yīng)字符串對(duì)象的引用,而不去創(chuàng)建新的字符串對(duì)象,這就是字符串intern機(jī)制。

 >>> i = "12"
 >>> j = "12"
 >>> i is j
 True

在詳細(xì)探討字符串intern機(jī)制之前,先看一個(gè)奇怪的問(wèn)題:

 >>> i = "1 2"
 >>> j = "1 2"
 >>> i is j
 False

 i = "1 2"
 j = "1 2"
 print(i is j)

輸出結(jié)果

 True

上述代碼分開(kāi)運(yùn)行,結(jié)果為False,但是合在一起結(jié)果卻為T(mén)rue,也就是說(shuō)分開(kāi)運(yùn)行的時(shí)候,i,j指向不同對(duì)象,而合在一起的時(shí)候i,j卻指向了相同對(duì)象。為了明白其中的緣由,需要簡(jiǎn)單理解python的編譯機(jī)制。

編譯機(jī)制

在python中,萬(wàn)物皆對(duì)象,包括代碼本身也是一種對(duì)象。python用code對(duì)象表示代碼,代碼編譯后產(chǎn)生code對(duì)象。通常一個(gè)作用域?qū)?yīng)一個(gè)code對(duì)象。

i = "1 2"
j = "1 2"
print(i is j)

def f():
  pass

編譯結(jié)果

2 0 LOAD_CONST 0 ('1 2')
2 STORE_NAME 0 (i)

3 4 LOAD_CONST 0 ('1 2')
6 STORE_NAME 1 (j)

5 8 LOAD_CONST 1 (<code object f at 0x00000200F257CF60, file "small_int.py", line 5>)
10 LOAD_CONST 2 ('f')
12 MAKE_FUNCTION 0
14 STORE_NAME 2 (f)
16 LOAD_CONST 3 (None)
18 RETURN_VALUE

Disassembly of <code object f at 0x00000200F257CF60, file "small_int.py", line 5>:
6 0 LOAD_CONST 0 (None)
2 RETURN_VALUE

上述代碼中編譯生成了兩個(gè)code對(duì)象,一個(gè)代表全局作用域,另一個(gè)代表函數(shù)f。

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

由于編譯的這個(gè)特性,在同一個(gè)code對(duì)象中的變量,如果它們引用了同一個(gè)常量,那么無(wú)論這個(gè)常量有沒(méi)有緩沖機(jī)制,它們引用的都是同一個(gè)對(duì)象。

a = "12"
b = "12"
c = "1 2"
d = "1 2"
e = 257
f = 257
g = 2424234234234234
h = 2424234234234234
print(a is b, c is d, e is f, g is h)

輸出結(jié)果

 True True True True

這個(gè)例子說(shuō)明,在同一個(gè)code對(duì)象當(dāng)中,常量(字面量)僅一份,這與緩沖機(jī)制無(wú)關(guān),是編譯特性。所以對(duì)于上述那個(gè)奇怪的問(wèn)題就可以解釋了,當(dāng)i,j在同一個(gè)code對(duì)象(同一個(gè)作用域)中引用常量"1 2",它們引用的都是同一個(gè)對(duì)象。而當(dāng)在python命令行中分開(kāi)執(zhí)行時(shí),對(duì)于每一條語(yǔ)句,都是一個(gè)單獨(dú)的code對(duì)象,這時(shí)起作用的是字符串intern機(jī)制,上述運(yùn)行結(jié)果說(shuō)明,字符串intern機(jī)制對(duì)"12"進(jìn)行了intern,而對(duì)"1 2"沒(méi)有進(jìn)行intern。

編譯機(jī)制與小整數(shù)對(duì)象池對(duì)比

i = 257
j = 257
a = i - 1
b = i - 1
c = i + 1
d = i + 1
print(i is j, a is b, c is d)

輸出結(jié)果

 True True False

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

這里有一點(diǎn)需要注意,沒(méi)有變量參與的運(yùn)算會(huì)被編譯器直接優(yōu)化成對(duì)應(yīng)的常量,進(jìn)而保存進(jìn)常量表中。

字符串intern機(jī)制與字符緩沖池
在編譯過(guò)程中,字符串intern機(jī)制將所有的變量名進(jìn)行intern,但對(duì)常量進(jìn)行的intern有一點(diǎn)特殊的限制。能夠intern的常量必須只包含[a-zA-Z0-9_],即字母數(shù)字加下劃線,如果含有其他字符,就不會(huì)intern。在運(yùn)行過(guò)程中,通過(guò)計(jì)算得到的字符串不會(huì)intern。

字符串有一個(gè)和小整數(shù)對(duì)象池相似的字符緩沖池,用于在運(yùn)行過(guò)程中緩存單個(gè)字符,所以計(jì)算得到的字符串雖然不會(huì)intern,但如果是單個(gè)字符,就會(huì)使用到字符緩沖池。

k = "bbb"
a = k[0]
b = k[0]
c = k[1:]
d = k[1:]
print(a, d)
print(a is b, c is d)

輸出結(jié)果

 b bb
 True False

可以看到,a和b確實(shí)指向同一個(gè)對(duì)象,而c和d指向不同對(duì)象,這就是字符緩沖池。

編譯機(jī)制與字符串intern對(duì)比

i = "1 2"
j = "12"
k = "__fjdslfjaskfas"

ii = "1 2"
jj = "12"
kk = "__fjdslfjaskfas"

def f():
  a = "1 2"
  b = "12"
  c = "__fjdslfjaskfas"
  return a is i, b is j, c is k

print("Code:", i is ii, j is jj, k is kk)
print(f"intern: {f()}")

輸出結(jié)果

 Code: True True True
 intern: (False, True, True)

i包含空格,包含空格的常量不會(huì)被intern,而其他兩個(gè)常量不包含其他字符,所以會(huì)被intern。

總結(jié)

1. python代碼被編譯成code對(duì)象,通常一個(gè)code對(duì)象對(duì)應(yīng)于一個(gè)作用域,作用域中重復(fù)出現(xiàn)的變量名以及常量在code中只保存一次。

2. 字符串intern機(jī)制主要作用于編譯過(guò)程,在編譯收集完變量和常量時(shí),對(duì)變量和常量進(jìn)行intern,而后構(gòu)建一個(gè)code對(duì)象。

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

4. 小整數(shù)對(duì)象池和字符緩沖池都是作用于運(yùn)行過(guò)程中,python緩存小的整數(shù)和字符,當(dāng)有變量使用這些對(duì)象時(shí),不用額外創(chuàng)建對(duì)象。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python Pycharm虛擬下百度飛漿PaddleX安裝報(bào)錯(cuò)問(wèn)題及處理方法(親測(cè)100%有效)

    Python Pycharm虛擬下百度飛漿PaddleX安裝報(bào)錯(cuò)問(wèn)題及處理方法(親測(cè)100%有效)

    最近很多朋友給小編留言在安裝PaddleX的時(shí)候總是出現(xiàn)各種奇葩問(wèn)題,不知道該怎么處理,今天小編通過(guò)本文給大家介紹下Python Pycharm虛擬下百度飛漿PaddleX安裝報(bào)錯(cuò)問(wèn)題及處理方法,真的有效,遇到同樣問(wèn)題的朋友快來(lái)參考下吧
    2021-05-05
  • 使用python把xmind轉(zhuǎn)換成excel測(cè)試用例的實(shí)現(xiàn)代碼

    使用python把xmind轉(zhuǎn)換成excel測(cè)試用例的實(shí)現(xiàn)代碼

    這篇文章主要介紹了使用python把xmind轉(zhuǎn)換成excel測(cè)試用例的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Pandas的MultiIndex多層索引使用說(shuō)明

    Pandas的MultiIndex多層索引使用說(shuō)明

    這篇文章主要介紹了Pandas的MultiIndex多層索引使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Python入門(mén)教程(三十一)Python的Try和Except

    Python入門(mén)教程(三十一)Python的Try和Except

    這篇文章主要介紹了Python入門(mén)教程(三十一)Python的Try Except,當(dāng)我們調(diào)用Python并發(fā)生錯(cuò)誤或異常時(shí),通常會(huì)停止并生成錯(cuò)誤消息,
    可以使用try語(yǔ)句處理這些異常,需要的朋友可以參考下
    2023-05-05
  • np.concatenate()函數(shù)數(shù)組序列參數(shù)的實(shí)現(xiàn)

    np.concatenate()函數(shù)數(shù)組序列參數(shù)的實(shí)現(xiàn)

    本文主要介紹了np.concatenate()函數(shù)數(shù)組序列參數(shù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python unittest生成測(cè)試報(bào)告過(guò)程解析

    Python unittest生成測(cè)試報(bào)告過(guò)程解析

    這篇文章主要介紹了Python unittest生成測(cè)試報(bào)告過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Python?中如何使用requests模塊發(fā)布表單數(shù)據(jù)

    Python?中如何使用requests模塊發(fā)布表單數(shù)據(jù)

    requests 庫(kù)是 Python 的主要方面之一,用于創(chuàng)建對(duì)已定義 URL 的 HTTP 請(qǐng)求,本篇文章介紹了 Python requests 模塊,并說(shuō)明了我們?nèi)绾问褂迷撃K在 Python 中發(fā)布表單數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧
    2023-06-06
  • django聯(lián)系人登錄界面案例詳解

    django聯(lián)系人登錄界面案例詳解

    在本案例中,將介紹如何使用Django框架創(chuàng)建一個(gè)簡(jiǎn)單的聯(lián)系人登錄界面,案例涉及前端HTML頁(yè)面設(shè)計(jì),CSS和JS的應(yīng)用,以及后端views.py的編寫(xiě),在后端處理中,密碼將通過(guò)MD5進(jìn)行加密,保證安全性,本文給大家介紹了django聯(lián)系人登錄界面案例詳解,感興趣的朋友一起看看吧
    2024-10-10
  • Django中QuerySet查詢優(yōu)化之prefetch_related詳解

    Django中QuerySet查詢優(yōu)化之prefetch_related詳解

    prefetch_related()和select_related()的設(shè)計(jì)目的很相似,都是為了減少SQL查詢的數(shù)量,但是實(shí)現(xiàn)的方式不一樣,下面這篇文章主要給大家介紹了關(guān)于Django中QuerySet查詢優(yōu)化之prefetch_related的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • python 實(shí)現(xiàn)非極大值抑制算法(Non-maximum suppression, NMS)

    python 實(shí)現(xiàn)非極大值抑制算法(Non-maximum suppression, NMS)

    這篇文章主要介紹了python 如何實(shí)現(xiàn)非極大值抑制算法(Non-maximum suppression, NMS),幫助大家更好的進(jìn)行機(jī)器學(xué)習(xí),感興趣的朋友可以了解下
    2020-10-10

最新評(píng)論

新蔡县| 宜黄县| 和顺县| 海林市| 鹤峰县| 东兰县| 邢台市| 九江市| 聂拉木县| 石台县| 金门县| 琼中| 高雄市| 那曲县| 仙居县| 庆元县| 新干县| 呼图壁县| 北海市| 宣武区| 呼和浩特市| 乌鲁木齐市| 平南县| 普安县| 苏尼特右旗| 汉中市| 博野县| 巴楚县| 行唐县| 南通市| 开封市| 全州县| 石首市| 雅江县| 柘城县| 泰州市| 若尔盖县| 揭西县| 蓬莱市| 白朗县| 九龙县|