對象引用抽减、可變性、垃圾回收

變量視作便利貼

變量 a橄碾,b 引用同一個列表

賦值:把變量分配給對象卵沉。先有對象
Python 變量類似 Java 中的引用式變量

標(biāo)識

對象一旦創(chuàng)建,它的標(biāo)識絕不會更改
可以把標(biāo)識理解為內(nèi)存地址法牲,is 運(yùn)算符比較兩對象的標(biāo)識史汗;id() 返回對象的標(biāo)識的整數(shù)表示

is 與 ==

  • == 比較的是值,is 比較的是兩個整數(shù) id
  • is 比 == 快拒垃,因?yàn)?is 不能重載停撞,而 == 背后是 a._eq_(b),object 的 _eq_ 比較的是兩對象的 id悼瓮,與 is 一致戈毒。
    但多數(shù)內(nèi)置類型覆蓋了此方法,考慮對象的屬性的值横堡,為此做相等性測試可能涉及大量處理工作埋市。
  • 變量與單例值比較應(yīng)使用 is。 x is None命贴;x is not None

tuple 的相對不可變性

  • 容器序列保存的是對象的引用
    單一數(shù)據(jù)類型的扁平序列在連續(xù)內(nèi)存中保存的是數(shù)據(jù)本身
  • tuple 不可變指 tuple 的物理內(nèi)容(保存的引用)不可變道宅。與引用的對象無關(guān)食听!


    區(qū)分賦值與 append

默認(rèn)做淺復(fù)制

  • 淺復(fù)制:只復(fù)制最外層容器,副本中的元素是源容器元素的引用
    使用構(gòu)造方法或 [ : ] 實(shí)現(xiàn)


    淺復(fù)制
  • 對于可變對象元素污茵,由于存放的是引用樱报,復(fù)制的也是引用。一個列表改變泞当,另外一個列表也改變迹蛤。
  • 對于不可變對象元素,雖然存放的是引用襟士,復(fù)制的也是引用笤受。
    但只要發(fā)生改變,實(shí)質(zhì)是創(chuàng)建了新對象敌蜂,原來的對象還是不會變。自然不會影響到另外一個列表

深復(fù)制

深復(fù)制:副本【與源本不共享內(nèi)部對象】copy.deepcopy(object)
淺復(fù)制:copy.copy(object)津肛,背后分別是 _copy_()章喉、_deepcopy_()

參數(shù)傳遞

Python 使用的是共享傳參(call by sharing),即形參是實(shí)參的別名


call by sharing
  • x 是不可變對象身坐,當(dāng) x += y 時秸脱,實(shí)質(zhì)創(chuàng)建了新對象,且新對象的作用域只在函數(shù)內(nèi)部蛇,原來的 x 沒變摊唇。
  • p 是可變對象,當(dāng) p += q 時涯鲁,p 已經(jīng)變了巷查。

不要使用可變對象作為函數(shù)默認(rèn)值

  • 默認(rèn)值在定義函數(shù)時計(jì)算(通常在加載模塊時,也就是導(dǎo)入模塊時)抹腿,即 passen=[] 只在加載模塊時執(zhí)行一次岛请,
    因此默認(rèn)值變成了函數(shù)這個對象的屬性。
    如果默認(rèn)值是可變對象警绩,而且修改了它的值崇败,后續(xù)函數(shù)調(diào)用都會受到影響。


    默認(rèn)值
  • 所以通常使用 None 作為接受可變值參數(shù)的默認(rèn)值

防御可變參數(shù)

def __init__(self, passengers=None):
    if passengers is None:
        passen = []
    else:
        self.passengers = list(passengers)
  • 用 None 作為接受可變值參數(shù)的默認(rèn)值
  • 如果直接 self.passengers = passengers 還是不夠妥當(dāng)肩祥,因?yàn)檫@樣形參和實(shí)參共享同一個對象后室,形參變了,實(shí)參也會發(fā)生改變混狠。list(passengers) 相當(dāng)淺復(fù)制了 passengers岸霹。反正一句話,不要直接對形參進(jìn)行操作檀蹋,否則會影響實(shí)參松申。應(yīng)該生成形參副本再操作云芦。

del 和垃圾回收

引用計(jì)數(shù)
CPython 垃圾回收算法。當(dāng)對象的引用歸零時贸桶,CPython 會在對象上調(diào)用_del_ 方法(前提是定義了)舅逸,然后釋放分配給對象的內(nèi)存。
分代垃圾回收
CPython 2.0 增加的算法皇筛。
如果一組對象全是相互引用琉历,如: a = [2, 3], b= [a, 5], a.append(b)
即使再出色的引用方式也會導(dǎo)致組中對象不可獲取。

del 不會刪除對象水醋,但 del 導(dǎo)致對象不可獲取從而被刪除

  • weakref.finalize(s1, bye):在 s1 引用的對象上注冊 bye 回調(diào)函數(shù)

弱引用

  • 上例中旗笔,finalize 持有 {1, 2, 3} 的弱引用
  • 在「緩存」中,經(jīng)常要引用對象拄踪,卻不讓對象存在時間超過所需時間
  • 弱引用不會增加對象引用數(shù)量蝇恶,弱引用引用的對象稱為「所指對象 referent」。弱引用不會影響 referent 被當(dāng)作垃圾回收


    弱引用
  • wref() 會返回被引用對象惶桐,因?yàn)檫@是控制臺會話撮弧,返回的對象會綁定到 _ 變量
  • 即使刪除了引用 a,仍有引用 _ 綁定對象 {0, 1}
  • 當(dāng)使用 wref() is None 時姚糊,_ 會綁定返回值 False贿衍,這時對象{0, 1} 就沒有引用了


    _ 自動綁定 wref() 返回對象

WeakValueDictionary

  • weakref.ref 類是底層接口(少用),較常用的是 finalize 和 weakref 集合(WeakKeyDictionary救恨、WeakValueDictionary贸辈、WeakSet)
  • WeakValueDictionary 類實(shí)現(xiàn)的是可變映射,
    里面的值是對象的弱引用肠槽,被引用的對象被回收后擎淤,
    對應(yīng)的鍵自動從 WeakValueDictionary 中刪除。
    常用作「緩存」
    WeakValueDictionary
  • stock 是WeakValueDictionary 的一個實(shí)例署浩,值是對象的弱引用揉燃。
  • del catalog 意味著被引用的對象被回收,按道理來說筋栋,stock 的鍵也會自動刪除炊汤,但是最后一個鍵被保留了。
  • 這時因?yàn)?for 循化中的 cheese 是全局變量弊攘,循環(huán)結(jié)束后綁定著對象 Cheese('ccc')抢腐,所以del catalog 后,對象 Cheese('ccc') 仍有引用 cheese襟交,所以不被當(dāng)作垃圾回收迈倍,直至 del cheese 后才被當(dāng)作垃圾回收,對應(yīng)的鍵也就自動刪除捣域。

weakSet
保存元素弱引用的集合類啼染,當(dāng)元素沒有強(qiáng)引用時宴合,自動刪除該元素。

對不可變對象的優(yōu)化

不可變對象的優(yōu)化
  • 使用一個元組創(chuàng)建另外一個元組(tuple()迹鹅、[:]卦洽、copy、deepcopy)斜棚,
    得到的是同一個對象阀蒂。
  • 共享字符串字面量是一種優(yōu)化措施,稱為「駐留 interning」
  • 類似的還有 bytes弟蚀、frozenset 實(shí)例蚤霞、較小的整數(shù),這樣能節(jié)省內(nèi)存义钉,提高解釋器速度昧绣。其實(shí)不了解也無傷大雅。

雜談

  • 從 object 繼承的_eq_ 方法(即 == 運(yùn)算符)比較的是對象 id
  • 用戶創(chuàng)建的類捶闸,其實(shí)例默認(rèn)可變
  • 可變對象是導(dǎo)致多線程編程難以處理的主要原因滞乙。某個線程改動對象后,不正確同步則損壞數(shù)據(jù)鉴嗤,過度同步又導(dǎo)致死鎖。
  • Python 沒有手動銷毀對象的機(jī)制序调。這是個好特性:如果能手動銷毀對象醉锅,那么指向?qū)ο蟮膹?qiáng)引用就不知怎么處理了。
  • CPython 中发绢,這樣寫是安全的:
    open('test.txt', 'wt', encoding='utf-8').write('1, 2, 3')
    因?yàn)槲募ο蟮囊脭?shù)量在 write 方法返回后歸零硬耍,銷毀內(nèi)存中文件對象之前,會立即關(guān)閉文件边酒。而在 Jpython 或 IronPython 中经柴,open().write() 卻是不安全的,因?yàn)樗鼈儾灰揽恳糜?jì)數(shù)墩朦。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坯认,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子氓涣,更是在濱河造成了極大的恐慌牛哺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件劳吠,死亡現(xiàn)場離奇詭異引润,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)痒玩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門淳附,熙熙樓的掌柜王于貴愁眉苦臉地迎上來议慰,“玉大人,你說我怎么就攤上這事奴曙”鸢迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵缆毁,是天一觀的道長番川。 經(jīng)常有香客問我,道長脊框,這世上最難降的妖魔是什么颁督? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮浇雹,結(jié)果婚禮上沉御,老公的妹妹穿的比我還像新娘。我一直安慰自己昭灵,他們只是感情好吠裆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烂完,像睡著了一般试疙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抠蚣,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天祝旷,我揣著相機(jī)與錄音,去河邊找鬼嘶窄。 笑死怀跛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柄冲。 我是一名探鬼主播吻谋,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼现横!你這毒婦竟也來了漓拾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戒祠,失蹤者是張志新(化名)和其女友劉穎晦攒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體得哆,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脯颜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了贩据。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栋操。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡闸餐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矾芙,到底是詐尸還是另有隱情舍沙,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布剔宪,位于F島的核電站拂铡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏葱绒。R本人自食惡果不足惜感帅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望地淀。 院中可真熱鬧失球,春花似錦、人聲如沸帮毁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烈疚。三九已至黔牵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爷肝,已是汗流浹背荧止。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阶剑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓危号,卻偏偏與公主長得像牧愁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子外莲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法猪半,類相關(guān)的語法,內(nèi)部類的語法偷线,繼承相關(guān)的語法磨确,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 相關(guān)概念 面向?qū)ο蟮娜齻€特征 封裝,繼承,多態(tài).這個應(yīng)該是人人皆知.有時候也會加上抽象. 多態(tài)的好處 允許不同類對...
    東經(jīng)315度閱讀 1,942評論 0 8
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,516評論 1 51
  • 雜事與行動之間声邦,要透過3個問題來連接: 第一乏奥,要不要做? 第二亥曹,我要的結(jié)果是什么邓了? 第三恨诱,我的下一步行動是什么? ...
    rieichin閱讀 131評論 0 0
  • 兒子今年五歲骗炉,當(dāng)然不在合法生育內(nèi)照宝,五年前屬超生,五年前為了要這個寶貝句葵,我辭去工作厕鹃,東奔西藏?fù)?dān)驚受怕,在外躲避八個月...
    沐源工作室閱讀 290評論 4 2