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