摘要:一對(duì)象引用基礎(chǔ)知識(shí)變量是標(biāo)注而不是容器。也就是說元組中不可變的是元素的標(biāo)識(shí),但元組的值會(huì)隨著引用的可變對(duì)象變化而變化。在中每個(gè)對(duì)象的引用都會(huì)有統(tǒng)計(jì)。弱引用不會(huì)妨礙對(duì)象被當(dāng)做垃圾回收。
導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之面向?qū)ο笃闹攸c(diǎn)知識(shí)及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。
本文重點(diǎn):
1、明確變量保存的是引用這一本質(zhì);一、對(duì)象引用基礎(chǔ)知識(shí)
2、熟悉對(duì)象引用的基礎(chǔ)知識(shí);
3、掌握深復(fù)制和淺復(fù)制;
4、熟悉函數(shù)傳參引用時(shí)潛在的麻煩并避免。
變量:是標(biāo)注而不是容器。對(duì)引用式變量而言,是把變量分配給對(duì)象,反過來理解則不合理。
別名:同一個(gè)對(duì)象的不同標(biāo)注就是別名,別名指向同一對(duì)象。
標(biāo)識(shí):可以把標(biāo)識(shí)理解為對(duì)象在內(nèi)存中的地址。每個(gè)變量都有標(biāo)識(shí)、類型和值。對(duì)象一旦創(chuàng)建,它的標(biāo)識(shí)絕不會(huì)變。is運(yùn)算符比較兩個(gè)對(duì)象的標(biāo)識(shí);id()函數(shù)返回對(duì)象標(biāo)識(shí)的整數(shù)表示,即對(duì)象的內(nèi)存地址。
相等性:用==運(yùn)算符比較兩個(gè)對(duì)象的值是否相等。注意a==b是語法糖,等同于a.__eq__(b)。
==和is的選擇:我們關(guān)注值的頻率比標(biāo)識(shí)要高。
當(dāng)比較變量和單例值的時(shí)候應(yīng)該用is。例如:X is None 或 X is not None。
is運(yùn)算符比==要快,因?yàn)閕s不能重載。
二、可變性 1、元組的相對(duì)不可變性:指tuple數(shù)據(jù)結(jié)構(gòu)的物理內(nèi)容(即保存的引用)不可變。也就是說元組中不可變的是元素的標(biāo)識(shí),但元組的值會(huì)隨著引用的可變對(duì)象變化而變化。
tuple,list,dict,set保存的是對(duì)象的引用,而str,byte,array.array保存的是對(duì)象的值(字符,字節(jié),數(shù)字)。
淺復(fù)制:當(dāng)復(fù)制tuple,list,dict,set時(shí),副本之間共享內(nèi)部對(duì)象的引用。copy.copy()
深復(fù)制:當(dāng)復(fù)制tuple,list,dict,set時(shí),副本之間不共享內(nèi)部對(duì)象的引用。copy.deepcopy()
eg:淺復(fù)制小例子
list1=[1,(55,66),[7,8,9]] list2=list(list1)#構(gòu)建副本默認(rèn)為淺復(fù)制 list2[1]+=(77,88)#對(duì)元組進(jìn)行+=運(yùn)算會(huì)解綁list2[1],并與右端運(yùn)算后的值之間重新綁定起來。 list2[2]+=[10]#對(duì)列表進(jìn)行iadd運(yùn)算會(huì)就地修改列表,不會(huì)發(fā)生重新綁定。 list2[0]*=3 list1[2].pop(0) print(list1) print(list2)
#輸出: [1, (55, 66), [8, 9, 10]] [3, (55, 66, 77, 88), [8, 9, 10]]
分析:list2是list1的副本,我們對(duì)list2的三個(gè)元素均作了改動(dòng),但只有列表元素的改動(dòng)影響到了list1。原因在于list1和list2的第三個(gè)列表元素共享引用,因此影響也會(huì)同步;元組因?yàn)榘l(fā)生了解綁的運(yùn)算所以影響未同步到list1;至于數(shù)值的影響不同步的原因是因?yàn)闇\復(fù)制針對(duì)str,byte,array.array這些對(duì)象直接將值重新保存到副本中來,不存在共享引用的內(nèi)部邏輯。
深復(fù)制注意事項(xiàng):
深復(fù)制處在循環(huán)引用的對(duì)象時(shí),深復(fù)制算法會(huì)進(jìn)入無限循環(huán)中。
一些對(duì)象可能會(huì)引用不該復(fù)制的外部資源或單例值,這些對(duì)象的深復(fù)制的結(jié)果可能太深。
3、函數(shù)的參數(shù)作為引用時(shí):Python唯一支持的參數(shù)傳遞模式是共享傳參。共享傳參指函數(shù)的各個(gè)形式參數(shù)獲得實(shí)參中各個(gè)引用的副本,即函數(shù)內(nèi)部的形參是實(shí)參的別名。
函數(shù)可能會(huì)修改作為參數(shù)傳入的可變對(duì)象。
(1)這個(gè)行為無法避免,除非在本地創(chuàng)建副本,或者使用不可變對(duì)象。
(2)因此在類中直接把參數(shù)賦值給實(shí)例變量之前一定要三思,因?yàn)檫@樣會(huì)為參數(shù)對(duì)象創(chuàng)建別名,修改傳入?yún)?shù)指向的可變對(duì)象。
eg:函數(shù)修改作為參數(shù)傳入的全局變量
def f(a, b): a += b return a a = [1, 2] b = [3, 4] f(a, b) print(a, b)#輸出[1, 2, 3, 4], [3, 4],此時(shí)列表a已經(jīng)發(fā)生變化。 t = (10, 20) u = (30, 40) f(t, u) print(t, u)#輸出((10, 20), (30, 40)),此時(shí)元組t沒有發(fā)生變化。
使用可變類型作為函數(shù)參數(shù)的默認(rèn)值有危險(xiǎn)。
原因在于包含此類函數(shù)的類的實(shí)例在未指定初始值時(shí)會(huì)使用同一個(gè)可變默認(rèn)值。當(dāng)一個(gè)實(shí)例就地修改參數(shù)時(shí)會(huì)影響其他實(shí)例對(duì)默認(rèn)值的調(diào)用。
主要采用引用計(jì)數(shù)算法。
在Python中每個(gè)對(duì)象的引用都會(huì)有統(tǒng)計(jì)。當(dāng)引用計(jì)數(shù)歸零時(shí),對(duì)象就會(huì)立即銷毀。
除了循環(huán)引用外沒有其他引用,處在循環(huán)引用的對(duì)象都會(huì)被銷毀。
2、弱引用某些情況下可能需要保存對(duì)象的引用,但不留存對(duì)象本身,此時(shí)可以借助弱引用實(shí)現(xiàn)。弱引用不會(huì)妨礙對(duì)象被當(dāng)做垃圾回收。
弱引用是一種低層機(jī)制,是weakref模塊中WeakValueDictionary、WeakKeyDictionary和WeakSet等有用的集合類,以及finalize函數(shù)的底層支持。
弱引用的局限性
弱引用所指對(duì)象可以是set,用戶自定義的類,list和dict的子類。不可以是int、tuple的實(shí)例及子類,也不可以是list實(shí)例或dict實(shí)例。
1、使用一個(gè)元組來構(gòu)造另一個(gè)元組,得到的其實(shí)是同一個(gè)元組。
2、比較字符串或整數(shù)是否相等時(shí),應(yīng)該使用==而不是is。這是由于Python解釋器內(nèi)部駐留的特性所導(dǎo)致的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/41476.html
摘要:每個(gè)變量都有標(biāo)識(shí)類型和值對(duì)象一旦創(chuàng)建它的標(biāo)識(shí)絕不會(huì)變標(biāo)識(shí)可以簡(jiǎn)單的理解為對(duì)象在內(nèi)存中的地址別名跟是別名指向如果增加新的內(nèi)容也會(huì)增加相等性為運(yùn)算符比較連個(gè)對(duì)象的值對(duì)象中保存的數(shù)據(jù)標(biāo)識(shí)為因?yàn)樗麄兌贾赶蜻@個(gè)列表比較對(duì)象的標(biāo)識(shí)元組相對(duì)不可變性元組保 a = [1,2,3,4] b = a 每個(gè)變量都有標(biāo)識(shí),類型和值.對(duì)象一旦創(chuàng)建,它的標(biāo)識(shí)絕不會(huì)變;標(biāo)識(shí)可以簡(jiǎn)單的理解為對(duì)象在內(nèi)存中的地址. ...
摘要:函數(shù)的參數(shù)作為引用時(shí)唯一支持的參數(shù)傳遞模式是共享傳參,它指函數(shù)的形參獲得實(shí)參中各個(gè)引用的副本,即形參是實(shí)參的別名。而在上面這個(gè)例子中,類的屬性實(shí)際上是形參所指向的對(duì)象所指對(duì)象,的別名。 《流暢的Python》筆記本篇是面向?qū)ο髴T用方法的第一篇,一共六篇。本篇主要是一些概念性的討論,內(nèi)容有:Python中的變量,對(duì)象標(biāo)識(shí),值,別名,元組的某些特性,深淺復(fù)制,引用,函數(shù)參數(shù),垃圾回收,de...
摘要:運(yùn)算符比較兩個(gè)對(duì)象的標(biāo)識(shí)函數(shù)返回對(duì)象標(biāo)識(shí)的整數(shù)表示。實(shí)際上,每個(gè)對(duì)象都會(huì)統(tǒng)計(jì)有多少引用指向自己。對(duì)象被銷毀了,調(diào)用了回調(diào),的值變成了。當(dāng)對(duì)象的引用數(shù)量歸零后,垃圾回收程序會(huì)把對(duì)象銷毀。引用的目標(biāo)對(duì)象稱為所指對(duì)象。 對(duì)象不是個(gè)盒子 showImg(https://segmentfault.com/img/bV95mW?w=1784&h=988); class Gizmo: def...
摘要:對(duì)象引用和可變性變量不是盒子,而是便利貼變量的賦值方式比如是將一個(gè)變量分配給一個(gè)對(duì)象比如整數(shù)。運(yùn)算符比較兩個(gè)對(duì)象的標(biāo)識(shí)函數(shù)返回對(duì)象標(biāo)識(shí)的整數(shù)表示。每個(gè)對(duì)象都會(huì)統(tǒng)計(jì)有多少引用指向自己。對(duì)象被銷毀執(zhí)行回調(diào)函數(shù)輸出 對(duì)象引用和可變性 變量不是盒子,而是‘便利貼’ >>> a = [1,2,3] >>> b = a >>> a.append(5) >>> a [1, 2, 3, 5] >>> ...
摘要:每個(gè)對(duì)象均有標(biāo)識(shí)符類型值。通常我們認(rèn)為當(dāng)這些對(duì)象被垃圾回收機(jī)制回收時(shí),它占用的外部資源即被釋放。造物主類型對(duì)象的類型幾乎影響了該對(duì)象的所有功能,在某種程度上,對(duì)象的標(biāo)識(shí)符也受其類型的影響。 原文地址 對(duì)象 對(duì)象(Objects)是python中數(shù)據(jù)的抽象,python中所有的數(shù)據(jù)均可以用對(duì)象或者是對(duì)象之間的關(guān)系來表示。每個(gè)對(duì)象均有標(biāo)識(shí)符(identity)、類型(type)、值(val...
閱讀 3893·2021-09-27 13:35
閱讀 1075·2021-09-24 09:48
閱讀 2904·2021-09-22 15:42
閱讀 2345·2021-09-22 15:28
閱讀 3151·2019-08-30 15:43
閱讀 2618·2019-08-30 13:52
閱讀 2976·2019-08-29 12:48
閱讀 1455·2019-08-26 13:55