- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > 編程語(yǔ)言 >
- Python中如何引用計數
Python中如何引用計數,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細講解,有這方面需求的人可以來(lái)學(xué)習下,希望你能有所收獲。
變量是內存引用
Python中的變量是內存引用。如果輸入x = [1,2]時(shí)會(huì )發(fā)生什么?[1,2]是對象。
回想一下,一切都是Python中的對象。[1,2]將在內存中創(chuàng )建。x是[1,2]對象的內存引用。
來(lái)看看下面的例子??梢哉业絰所引用的內存地址。請務(wù)必只使用id(x),它會(huì )以10為基數,而十六進(jìn)制函數會(huì )將其轉換為十六進(jìn)制。
x = [1, 2] print(hex(id(x))) # output: 0x32ebea8
引用計數
現在已經(jīng)在內存中創(chuàng )建了一個(gè)list對象,而且x對該對象進(jìn)行了引用。那么y=[1,2]和y=x有什么區別?
當輸入y=[1,2]時(shí),它將在內存中創(chuàng )建一個(gè)新的list對象,并且y將引用它。
x = [1, 2] y = [1, 2] print(hex(id(x))) # output: 0x101bea8 print(hex(id(y))) # output: 0x31a5528
而當輸入y=x時(shí),等同于告訴Python希望y 變量引用x變量引用的內容。因為變量是內存引用的。
可以確認x和y引用同一個(gè)對象。
x = [1, 2] y = x print(hex(id(x))) # output: 0x74bea8 print(hex(id(y))) # output: 0x74bea8
引用計數的數目
接下來(lái)的問(wèn)題是,有多少變量引用同一個(gè)對象?
錯誤的用法:
我看到有些人在使用sys.getrefcount(var)時(shí)不知道如何傳遞var,而是向對象添加引用。一起看看下面的例子。
輸出3,而期望的卻是2(x andy)。發(fā)生這種情況是因為將x傳遞給getrefcount函數時(shí)又添加了一個(gè)引用。
from sys import getrefcount x = [1, 2] y = x print(hex(id(x))) # output: 0xb65748 print(hex(id(y))) # output: 0xb65748 print(getrefcount(x)) # output: 3
更好的用法:
可以使用內置的ctypes模塊來(lái)找到預期的結果。必須將x的id傳遞給from_address函數。
from ctypes import c_long x = [1, 2] y = x print(hex(id(x))) # output: 0x3395748 print(hex(id(y))) # output: 0x3395748 print(c_long.from_address(id(x)).value) # output: 2
概言之,錯誤的用法是傳遞變量,而更好的用法則是傳遞變量的id,這意味著(zhù)只傳遞基數為10的數字,而不是變量。
當對象消失時(shí)
當沒(méi)有變量引用對象時(shí)會(huì )發(fā)生什么?
對象將從內存中刪除,因為沒(méi)有引用該對象的內容。不過(guò)也有例外:如果有循環(huán)引用,garbage collector 將開(kāi)始奏效。
為什么使用可變對象
不可變對象由于性能原因,結果可能與預期不同。查看下面的例子,觀(guān)察輸出是如何變化的。
import sys import ctypes """Some Mutable Objects """ a =list() b =set() c =dict() d =bytearray() """ Some ImmutableObjects """ e =tuple() f =int() g =str() print(sys.getrefcount(a),ctypes.c_long.from_address(id(a)).value) # output: 2 1 print(sys.getrefcount(b),ctypes.c_long.from_address(id(b)).value) # output: 2 1 print(sys.getrefcount(c),ctypes.c_long.from_address(id(c)).value) # output: 2 1 print(sys.getrefcount(d),ctypes.c_long.from_address(id(d)).value) # output: 2 1 print(sys.getrefcount(e),ctypes.c_long.from_address(id(e)).value) # output: 1298 1297 print(sys.getrefcount(f),ctypes.c_long.from_address(id(f)).value) # output: 209 208 print(sys.getrefcount(g),ctypes.c_long.from_address(id(g)).value) # output: 59 58
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站