亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

小整數(shù)對象池

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

>>> i = -5
>>> j = -5
>>> i is j # i和j是同一個對象
True
>>> i = 256
>>> j = 256
>>> i is j # i和j是同一個對象
True
>>> i = 257
>>> j = 257
>>> i is j # i和j是不同對象
False

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

字符串intern

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

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

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

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

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

輸出結(jié)果

 True

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

編譯機制

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

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

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

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

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

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

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

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

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

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

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

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

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確實指向同一個對象,而c和d指向不同對象,這就是字符緩沖池。

編譯機制與字符串intern對比

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包含空格,包含空格的常量不會被intern,而其他兩個常量不包含其他字符,所以會被intern。

總結(jié)

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

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

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

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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python使用循環(huán)打印所有三位數(shù)水仙花數(shù)的實例

    python使用循環(huán)打印所有三位數(shù)水仙花數(shù)的實例

    今天小編就為大家分享一篇python使用循環(huán)打印所有三位數(shù)水仙花數(shù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Window版下在Jupyter中編寫TensorFlow的環(huán)境搭建

    Window版下在Jupyter中編寫TensorFlow的環(huán)境搭建

    這篇文章主要介紹了Window版下在Jupyter中編寫TensorFlow的環(huán)境搭建,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Python用requests庫爬取返回為空的解決辦法

    Python用requests庫爬取返回為空的解決辦法

    這篇文章主要介紹了Python用requests庫爬取返回為空的解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • PyTorch 解決Dataset和Dataloader遇到的問題

    PyTorch 解決Dataset和Dataloader遇到的問題

    今天小編就為大家分享一篇PyTorch 解決Dataset和Dataloader遇到的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 利用Python實現(xiàn)讀取Word表格計算匯總并寫入Excel

    利用Python實現(xiàn)讀取Word表格計算匯總并寫入Excel

    這篇文章主要給大家介紹了關(guān)于如何利用Python實現(xiàn)讀取Word表格計算匯總并寫入Excel的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-01-01
  • Python實現(xiàn)獲取前100組勾股數(shù)的方法示例

    Python實現(xiàn)獲取前100組勾股數(shù)的方法示例

    這篇文章主要介紹了Python實現(xiàn)獲取前100組勾股數(shù)的方法,涉及Python數(shù)值計算與判斷相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • python里反向傳播算法詳解

    python里反向傳播算法詳解

    在本篇文章了小編給大家整理的是一篇關(guān)于python里反向傳播算法詳解內(nèi)容,有興趣的朋友們可以學習下。
    2020-11-11
  • 詳解Python中for循環(huán)是如何工作的

    詳解Python中for循環(huán)是如何工作的

    如果你對python中的for循環(huán)不是很清楚,那么建議你看看這篇文章,本文主要給大家介紹了關(guān)于Python中for循環(huán)是如何工作的相關(guān)資料,介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • Python如何爬取b站熱門視頻并導入Excel

    Python如何爬取b站熱門視頻并導入Excel

    這篇文章主要介紹了Python如何爬取b站熱門視頻并導入Excel,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • 棧和隊列數(shù)據(jù)結(jié)構(gòu)的基本概念及其相關(guān)的Python實現(xiàn)

    棧和隊列數(shù)據(jù)結(jié)構(gòu)的基本概念及其相關(guān)的Python實現(xiàn)

    這篇文章主要介紹了棧和隊列數(shù)據(jù)結(jié)構(gòu)的基本概念及其相關(guān)的Python實現(xiàn),先進先出和后進先出的知識也已經(jīng)成為了計算機學習中的老生常談了:D需要的朋友可以參考下
    2015-08-08

最新評論