婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳解Python垃圾回收機制和常量池的驗證

詳解Python垃圾回收機制和常量池的驗證

熱門標簽:400電話 申請 條件 賓館能在百度地圖標注嗎 南京crm外呼系統排名 crm電銷機器人 云南地圖標注 汕頭電商外呼系統供應商 電銷機器人 金倫通信 北京外呼電銷機器人招商 鄭州智能外呼系統中心

Python的引入

人類認識世界是從認識世界中的一個又一個實物開始,然后再對其用語言加以描述。例如當中國人看到蘋果時,便會用中文“蘋果”加以描述,而用英語的一些國家則會用“apple”加以描述。

以上說到的中文和英文都是人類認識并描述世界的一個工具,而在計算機的世界中,為了讓計算機去認知世界,從而幫助人類完成更多的任務。在計算機領域中也發展了語言這個工具,從早期的機器語言到匯編語言再到現在使用范圍較廣的高級語言。而我們接下來要介紹的Python則屬于高級語言這一分支。

變量的引入

為什么要有變量

上面說到Python是計算機世界中用來描述外部世界的,并且也提及了世界就是一個又一個實物的堆疊,描述世界其實就是去描述那一個又一個實物,人類如此,計算機也是如此。因此計算機語言開發者們為了使用計算機語言的人更好的在計算機中去描述這些實物,便在計算機語言中引入了變量這個概念,Python也不例外。簡單點說,變量就是用來描述世間萬物的。

定義變量

為了在計算機書寫方便,定義一變量也有一定的規則,在這里我們僅說說Python中變量的定義規則,首先我們先定義兩個變量:

name = 'chenyoude'
year = 2021

上述代碼中我們便定義了兩個變量,從上面定義的兩個變量中,我們可以看到,變量的組成分為三個部分:

  1. 變量名:反應變量值所描述的意義,并且可以用來引用變量值。
  2. 賦值符號:賦值。
  3. 變量值:存放數據,用來記錄現實世界中的某種狀態。

常量引入

上面簡單講解了Python中的變量,通過字面意思,可以看到變量其實是一個變化的量,例如,下面這個實例:

year = 2021
year = year + 1
print(year) # 輸出結果:2022

剛開始我們賦予了year一個變量值為2021,當我們對year進行加1操作時,可以發現year值變成了2022。對于上述現象我們不難理解,因為之前說過Python中變量是用來描述世間萬物的,世間萬物在現實中是可以變化的,變量當然也可以隨之變化。

但是在某個局部范圍內,變量可能是不會變化的,例如在2021年這一年,都只會是2021年,沒有人會說2021年是2022年。如果你有豐富的開發經驗,會明白變量定義出來不是存放在那里給你看的,更多的是要拿來用的。也就是說如果在2021年中的某個程序需要使用year這個變量,但這個變量是不需要進行修改的。為了防止誤操作對year這個變量進行了修改,計算機語言便設計了常量這個概念,也就是說常量相對于變量是一個不會變化的量。

在Python中,有沒有常量呢?不嚴格的講,其實是有的,只是在定義常量的時候常量名必須的全大寫,例如,下面這個實例:

YEAR = 2021
YEAR = YEAR + 1
print(YEAR) # 輸出結果:2022

上面這個常量的實例令人大吃一驚,因為使用常量YEAR后和使用變量year的結果一致,也就是說常量YEAR遭到了更改。但是,稍微解釋你就明白了。

在Python中,雖然也和其他很多計算機語言一樣擁有常量這個概念,但更多的是約定俗成的,Python并沒有嚴格的對常量進行控制,只是規定常量名必須全部大寫。原因很簡單:都是常量了,你為什么還要修改?

常量池引入

上面講到常量就是一個不會變化的變量,嚴格的講,在Python中是沒有常量這個概念的。但是,在Python中又有另外一種例外,那就是常量池,為了搞清楚常量池,首先我們得弄明白Python的幾個小知識,接下來一一敘說。

Python解釋器

上面提及到Python是計算機用來描述世間萬物的一種語言,由于計算機沒有人腦那么強大,計算機更多的只是認識高低壓電頻,再通過對高低壓電頻的轉化進而編碼成我們看到的一個又一個字符,也就是說計算機是無法直接認識利用Python寫下的字符的。(此處設計計算機組成原理,不多做介紹)

也就是說,當我們利用Python寫下一個又一個字符并且交給電腦時,需要通過編碼這個過程,而這個編碼的過程有時候也被稱為解釋。解釋的原理就相當于從中文轉成英文,只不過此時不是需要讓英文使用者看懂中文,而是讓計算機能夠看懂Python。

中文轉成英文的時候,可能需要一個翻譯員或一個翻譯軟件,利用Python寫下的字符轉化為計算機能看懂的語言同樣如此,這個轉化過程也需要一個外物的幫助——Python解釋器。

Python變量存儲機制

假設我們使用Python解釋器定義了以下一個變量:

year = 2021

當我們通過字符定義變量時,一定會好奇這些變量被Python解釋器解釋后到底去了哪?如果對計算機的組成熟悉的同學,一定會清楚計算機的核心組件為:CPU、內存、外存、輸入設備、輸出設備。也就是說,這些字符應該存儲在這些核心組件中。在這里就不賣關子了,當我們通過字符定義變量并對其用Python解釋器進行解釋時,他們會以計算機能看懂的形式進入內存當中。

上面講的對于很多非科班出身的朋友可能很難理解,在這里將它生動化。現在假設江西師范大學相當于電腦內存,每當有一批新學生進入師大時,師大都會開辟出一個新教室給這批新同學使用,并且會給每一個教室一個獨一無二的教室牌號。由于把師大看作是內存,這批新同學就可以看成是變量值,而教室牌號就是變量名。也就是說,對于師大這個大內存,每定義一個變量year=2021,就會在這個大內存中開辟一個小空間,小空間中放變量值2021,然后大內存會給這個小空間定義一個變量名year,此時變量名year指向變量值2021。

上面說到每當Python解釋器解釋一個變量時,會將這個變量存放到內存中的一個小空間中,但如何知道這個小空間的具體位置呢?此處介紹Python的一個內置函數id(),通過這個函數可以獲取某一個變量所在的內存地址,例如下面這個實例:

year = 2021
print(id(year)) # 輸出4499932432

Python垃圾回收機制

對于上述師大的例子,此處再做延伸。由于那一批學生所在班級新轉來了幾位同學,需要那一批學生更換更大一點教室,也就是給他們一個新的教室。那么學校應該會這樣處理,首先開辟一個新的教室,然后拿下那一批學生原有教室的教室牌號更換到這個新教室,最后會清空原有教室。

在Python中,也是如此,如果到了新的一年,我們會重新定義一個year變量,也就是year=2022。如果這是在同一個程序中如此做,Python會沿用上述更換教室的方法,它首先會解除year和2021的連接,開辟一個新內存存放變量值2022,讓year與2022連接。此時,會發現2021這個變量值只有變量值而沒有變量名,因此這個沒有變量名的變量值會變成Python眼中的一個垃圾變量,從而觸發Python垃圾回收機制,對這個2021所在的內存空間進行回收。

為了更好地理解Python垃圾回收機制,可以看下面這個例子:

year = 2021
print(id(year)) # 輸出4499932720
print(year) # 輸出2021

year = 2022
print(id(year)) # 輸出4499932560
print(year) # 輸出2022

通過上述例子,可以看到當新定義了一個year變量時,year會與新的變量進行一個連接。當然,此處所說的垃圾回收機制只是為了引入引用計數這個概念,并不是完全正確的解釋,并且上述實例還無法證明變量值2021所在內存是否被回收,下面將通過引用計數的實例會進一步說明并重新解釋垃圾回收機制。

引用計數

上面講到如果某個變量值綁定著變量名,就是一個正常的變量,如果該變量值沒有綁定著門牌號,這個變量就是一個垃圾變量,對于垃圾變量,Python會觸發垃圾回收機制回收這個變量所占有的內存。進而可以想到,Python中一個變量名一定只能對應一個變量值。

在這里我們就不能沿用師大這個例子了,而得引出一個新的名詞——引用計數。

為了解釋引用計數,我們首先得明白在Python中,當定義了一個變量值為2021的變量時,它可以表示年份、也可以表示山的高度…也就是說一個變量名只能對應一個變量值,但是一個變量值可以對應不同的變量名,這種設計也是比較合理的。

現在我們引出引用計數這個概念,當相同的變量值被賦予不同的變量名時,變量值每增加一個變量名的賦予,則該變量值的引用計數加1。由于我們可以通過Python內置sys模塊中的getrefcount()函數獲取某一個變量的引用計數(getrefcount輸出值默認從3開始),可以通過下面這個例子感受下:

import sys

# 引用計數初始值為3
print(sys.getrefcount(2021)) # 輸出為3

year = 2021
print(sys.getrefcount(2021)) # 輸出為4

height = 2021
print(sys.getrefcount(2021)) # 輸出為5

del year
print(sys.getrefcount(2021)) # 輸出為4

從上述代碼可以看出變量值2021的引用計數由于每一次賦予新的變量名,引用計數都會增加,而當我們利用del關鍵字刪除變量值2021的一個變量名year時,引用計數則會減少。

為了更加嚴謹的表達引用計數,此處不得不再次深入,引用計數字面意思可以理解為引用的次數,也就是說上面的例子其實并不嚴謹,更嚴謹的講,只有當一個變量值每一次被直接或間接引用時,引用計數才會增加,在Python中讓引用計數增加共有三種方法:

  1. 變量被創建,變量值引用計數加1
  2. 變量被引用,變量值引用計數加1
  3. 變量作為參數傳入到一個函數,變量值引用計數加2

具體看下述實例:

import sys

# 引用計數初始值為3
print(sys.getrefcount(2021)) # 輸出為3

# 變量被創建,變量值引用計數加1
year = 2021
print(sys.getrefcount(2021)) # 輸出為4

# 變量被引用,變量值引用計數加1
height = year
print(sys.getrefcount(2021)) # 輸出為5

# 變量作為參數傳入到一個函數,變量值引用計數加2
def func(year):
  print(sys.getrefcount(year)) 

func(year) # 輸出為7

Python中既然有增加引用計數的方法, 也當然會減少引用計數的方法,共有以下4種:

  1. 變量值對應的變量名被銷毀
  2. 變量值對應的變量名被賦予新的值
  3. 變量值對應的變量名離開它的作用域
  4. 變量值對應的變量名的容器被銷毀

重看Python垃圾回收機制

有了getrefcount()方法并通過引用計數,我們就可以解開垃圾回收機制遺留的一個問題——如何判斷是否觸發了垃圾回收機制。每當一個變量定義,他的getrefcount輸出值為3,而如果該變量值被垃圾回收機制回收,則它的getrefcount輸出值回到3,可以通過下面實例驗證上述猜想:

import sys

print(sys.getrefcount(2021)) # 輸出為3

year = 2021
print(sys.getrefcount(2021)) # 輸出為4
print(id(year)) # 輸出4499932720
print(year) # 輸出2021

year = 2022
print(sys.getrefcount(2021)) # 輸出為3
print(id(year)) # 輸出4499932560
print(year) # 輸出2022

通過上述實例,可以發現由于變量值2021對應的變量名被新的變量值2022引用,它的getrefcount輸出值為3,引用計數變成了0,因此可以證明Python觸發了垃圾回收機制。

如果對上述驗證Python觸發垃圾回收機制的實例深入挖掘,會發現當把year賦給變量值2022時,變量值的2021的引用計數為0,此時觸發了Python的垃圾回收機制,那么是否可以表明只有當變量值2021的引用計數為0時才能觸發垃圾回收機制呢?而不是上一次說的當變量值的變量名被新的變量值被引用了才會銷毀呢?因為變量值可以對應多個變量名,下面通過下述實例驗證:

import sys

print(sys.getrefcount(2021)) # 輸出為3

year = 2021
print(sys.getrefcount(2021)) # 輸出為4

height = 2021
print(sys.getrefcount(2021)) # 輸出為5

year = 2022
print(sys.getrefcount(2021)) # 輸出為4

del height
print(sys.getrefcount(2021)) # 輸出為3

通過上述實例,可以發現由于定義一個變量后,該變量對應的變量值引用計數可以不斷增加,而只要引用計數不為0,那么Python就一直還在內存中保留著這個變量值并且對其引用,只有當該變量的引用計數為0時,Python才會觸發垃圾回收機制對該變量值進行回收,這才是比較正確的垃圾回收機制。當然,如果深入,Python的回收機制還有分代回收,此處不做延展,了解上述這些就足矣了解接下來講的小整數池。

常量池

在上述各個知識的打通之后,現在可以正式引入常量池這個概念。上面講到在Python中嚴格的講是沒有常量這個概念的,即使你通過約定俗成的方法定義了一個常量,但這個常量也只是一個變量,也就是說只要你對這個常量做出修改,這個常量原有對應的常量值引用計數就會變成0,由于常量等同于變量,它一樣會被Python垃圾回收機制回收。

但是在Python中,存在著一些例外,這些例外就是一個小整數池,顧名思義,小整數池表示的是從-5到256范圍內的整數,這些整數定義出來后就是一個常量,也就是說他們的引用計數即使為0,也不會被Python的垃圾回收機制回收,可以通過下述實例驗證:

import sys

first_l = [] # 定義列表l存儲[-5,256]中的所有整數的引用計數
add_l = [] # 定義列表add_l存儲[-5,256]中的所有整數的引用計數加1后的引用計數
del_l = [] # 定義列表del_l存儲[-5,256]中的所有整數的引用計數減1后的引用計數

for i in range(-5, 256):
  first_l.append(sys.getrefcount(i))
  add = i
  add_l.append(sys.getrefcount(i))
  del add
  del_l.append(sys.getrefcount(i))

first_l.sort()
add_l.sort()
del_l.sort()

print(f'min(first_l): {min(first_l)}') # 獲取[-5,256]中所有整數的最小引用計數,輸出為4
print(f'min(add_l): {min(add_l)}') # 獲取[-5,256]中所有整數的最小引用計數,輸出為5
print(f'min(del_l): {min(del_l)}') # 獲取[-5,256]中所有整數的最小引用計數,輸出為4

從上述實例可以看出,[-5,256]中的整數的getrefcount默認初始值為4,也就是說即使沒有對這些整數進行初始化的創建,Python早已對他們進行了引用,即使他們的引用計數為0,他們也不會也不可能被刪除,因為他們從Python解釋器啟動開始就已經被生成。

當然,也可以通過垃圾回收機制判斷小整數池中的整數是否會被垃圾回收機制回收,可用如下實例證明(由于Pycharm等解釋器會一次性編譯整個文件,固使用終端編輯代碼):

>>> a = 5
>>> id(a)
4529334480
>>> del a
>>> b = 5
>>> id(b)
4529334480
>>>
>>> a = 257
>>> id(a)
4533920752
>>> del a
>>> b = 257 # 消除分代回收對結果的影響
>>> del b
>>> b = 257
>>> id(b)
4531031792
>>>

從上述實例中可以看出,變量值5即使被垃圾回收機制回收后,再次創建變量值為5的變量,該變量的內存地址始終無變化,即該變量未被垃圾回收機制回收,小整數池中的其他整數同理;而變量值257卻已經被垃圾回收機制回收,非小整數池中的其他變量同理。

當然,還可以通過下述方法查看這些小整數池的整數的內存地址的變化,如下:

a = 256
b = int("256")
print(id(a), id(b)) # 4544968752 4544968752

a = 257
b = int("257")
print(id(a), id(b)) # 4548719792 4546289360

a = -5
b = int("-5")
print(id(a), id(b)) # 4544960400 4544960400

a = -6
b = int("-6")
print(id(a), id(b)) # 4690036912 4546289360

對于上述實例,在Python中,由于每生成一個變量便會開辟一個新的內存空間給該變量,但是上述實例表明當變量值為-5和256時,每次開辟的內存空間地址都是一樣的;而當變量值不屬于[-5,256]時,每次定義變量值時,內存空間的地址都是不一樣的。

總結

在Python中,變量是用來描述世間萬物的,變量顧名思義是變化的一個量,而在某一個局部范圍內,有些量可能是不會變化的,因此語言設計者在計算機中定義了常量這個概念,但是在Python中并沒有規定的常量,只有約定俗稱的常量,也就是變量名全大寫的則是常量。但是Python中有一個另外,也就是小整數池[-5,256],在這個小整數池中的整數對于Python來說就是一個常量,因為從引用計數的打印中可以看出它在Python解釋器啟動的時候就已經生成并占用了一個固定的內存空間,并且不會因為引用計數變為0之后就會被Python的垃圾回收機制回收,而這些小整數池也可以稱作Python的常量池。

以上就是詳解Python垃圾回收機制和常量池的驗證的詳細內容,更多關于Python垃圾回收機制和常量池的驗證的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • Python編程之字符串模板(Template)用法實例分析
  • Python的string模塊中的Template類字符串模板用法
  • python常量折疊基礎知識點講解
  • python接口自動化如何封裝獲取常量的類
  • Python將字符串常量轉化為變量方法總結
  • 在Python中定義一個常量的方法
  • python中的常量和變量代碼詳解
  • 深入理解Python中的內置常量
  • 深入理解Python變量與常量
  • Python中實現常量(Const)功能
  • Python基礎之文本常量與字符串模板

標簽:文山 昆明 石家莊 梅州 西寧 錫林郭勒盟 懷化 浙江

巨人網絡通訊聲明:本文標題《詳解Python垃圾回收機制和常量池的驗證》,本文關鍵詞  詳解,Python,垃圾,回收,機制,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解Python垃圾回收機制和常量池的驗證》相關的同類信息!
  • 本頁收集關于詳解Python垃圾回收機制和常量池的驗證的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美性受xxxx黑人xyx性爽| 97精品电影院| 成人福利电影精品一区二区在线观看| 欧美日韩在线不卡| 亚洲成人手机在线| 在线播放中文字幕一区| 性做久久久久久免费观看| 欧美性猛片xxxx免费看久爱| 亚州成人在线电影| 日韩三级视频在线观看| 黄一区二区三区| 国产精品理论片在线观看| 不卡视频在线看| 亚洲精品免费一二三区| 欧美日韩国产在线观看| 亚洲成人免费视频| 欧美不卡激情三级在线观看| 高清av一区二区| 一区二区三区久久久| 欧美高清视频一二三区 | 麻豆精品在线看| 久久蜜桃av一区二区天堂| 国产东北露脸精品视频| 一区二区三区在线观看欧美| 欧美成人艳星乳罩| 99国内精品久久| 日韩一区精品字幕| 欧美激情资源网| 色www精品视频在线观看| 日韩高清在线电影| 中文字幕亚洲精品在线观看| 日韩亚洲欧美高清| 日韩欧美一级特黄在线播放| 国产成人精品亚洲日本在线桃色| 欧美一二区视频| av电影在线观看不卡| 日本麻豆一区二区三区视频| 国产精品国产三级国产三级人妇| 欧美高清dvd| 97国产精品videossex| 国内精品写真在线观看| 亚洲三级在线免费| 精品少妇一区二区三区日产乱码| 欧美三级韩国三级日本一级| 不卡一区二区中文字幕| 国产乱人伦精品一区二区在线观看| 最新欧美精品一区二区三区| 综合av第一页| 欧美成人三级电影在线| 欧美日韩一区二区三区视频| 国产成人免费视频网站高清观看视频| 精品sm在线观看| 欧美精品色一区二区三区| eeuss鲁片一区二区三区在线观看| 青青国产91久久久久久| 尤物在线观看一区| 亚洲欧美综合另类在线卡通| 国产亚洲综合在线| 精品国产百合女同互慰| 欧美一级久久久久久久大片| 欧美色精品在线视频| 91视视频在线直接观看在线看网页在线看| 久久国内精品视频| 久久国产欧美日韩精品| 日韩精品每日更新| 亚洲成人av福利| 亚洲福利一区二区三区| 免费成人在线网站| 一区二区三区在线免费播放| 亚洲欧美日韩在线不卡| 亚洲视频网在线直播| 中文字幕人成不卡一区| 亚洲日本一区二区| 亚洲一区二区三区视频在线 | 国产精品麻豆久久久| 久久综合九色综合97婷婷女人| 欧美精品一区二区三区蜜臀| 久久一区二区视频| 国产精品乱码一区二区三区软件 | 亚洲国产一区在线观看| 午夜精品久久久久久久| 丝袜亚洲另类欧美综合| 美女一区二区久久| 国产久卡久卡久卡久卡视频精品| 国产不卡在线播放| 色综合婷婷久久| 67194成人在线观看| 精品91自产拍在线观看一区| 国产精品私人自拍| 亚洲色图制服诱惑 | 91成人在线观看喷潮| 欧美日本国产视频| 欧美大片在线观看| 日韩美女精品在线| 午夜一区二区三区视频| 精品一区二区影视| 一本一道久久a久久精品| 91精品国产手机| 国产欧美一区视频| 一区二区在线电影| 精品一区二区三区在线播放视频 | 欧美韩日一区二区三区| 中文字幕亚洲电影| 日韩av电影天堂| 91在线观看高清| 精品人伦一区二区色婷婷| 亚洲日本va在线观看| 人人超碰91尤物精品国产| 日韩欧美国产电影| 中文字幕日韩一区二区| 日本特黄久久久高潮| 成人免费视频app| 日韩欧美在线影院| 亚洲aⅴ怡春院| av一区二区三区在线| 亚洲精品一区二区三区精华液| 亚洲高清不卡在线| 91视频在线看| 国产精品国产自产拍高清av| 麻豆极品一区二区三区| 欧美午夜片在线观看| 综合分类小说区另类春色亚洲小说欧美| 久久99久久久久久久久久久| 欧美性极品少妇| 亚洲欧美电影一区二区| 成人中文字幕在线| 久久久精品国产免大香伊| 日本美女一区二区三区视频| 欧美人体做爰大胆视频| 一区二区日韩av| 91高清视频在线| 亚洲自拍偷拍网站| 色综合 综合色| 亚洲蜜臀av乱码久久精品| 不卡一区二区三区四区| 136国产福利精品导航| 波多野结衣精品在线| 中文字幕乱码一区二区免费| 风间由美一区二区三区在线观看| 日本一区二区三区视频视频| 成人av网站在线观看| 中文字幕成人在线观看| 99久久久国产精品| 亚洲综合999| 日韩一区二区电影| 极品少妇xxxx偷拍精品少妇| 久久久精品一品道一区| 成人免费高清在线| 国产精品不卡视频| 在线观看不卡视频| 视频一区在线播放| 久久综合九色综合欧美亚洲| 成人小视频免费在线观看| 中文字幕va一区二区三区| 久久免费国产精品| 国产电影一区在线| 国产精品久久久久久久久免费相片| 成人91在线观看| 亚洲一卡二卡三卡四卡五卡| 在线不卡的av| 国产自产v一区二区三区c| 中文字幕av不卡| 日本精品免费观看高清观看| 视频在线观看91| 国产欧美一区二区三区在线看蜜臀| 成人av电影在线播放| 午夜精品福利在线| 精品久久99ma| 色偷偷成人一区二区三区91| 免费在线看成人av| 中文字幕精品在线不卡| 宅男噜噜噜66一区二区66| 成人av电影在线网| 久久精品国内一区二区三区| 中文字幕一区二区三| 日韩视频在线永久播放| 91亚洲精华国产精华精华液| 免费在线观看一区二区三区| 一区二区在线免费| 国产精品国产三级国产aⅴ中文| 在线播放中文字幕一区| 成人美女视频在线观看| 免费观看日韩电影| 成人免费视频在线观看| 久久综合狠狠综合| 欧美一区二区三区四区五区| 91福利在线观看| 成人黄色在线视频| 久久99久久99精品免视看婷婷 | 婷婷中文字幕一区三区| 国产免费成人在线视频| 欧美一区二区三区视频在线观看| 99国产精品国产精品久久| 国产综合色产在线精品| 天天亚洲美女在线视频| 亚洲男人电影天堂| 亚洲欧美中日韩| 国产精品久久久久影院色老大 | 久久综合久久久久88| 欧美日韩你懂得|