標籤:

第八章 對象引用、可變性

本章討論的是對象與對象名稱之間的區別。名稱不是對象,而是單獨的東西。

變數不是盒子

Python中的變數很像java中的引用變數,也就是說,變數里存著的並不是變數本身,而是對於內容的引用(C中的指針)。這樣說起來可能有點繞口,我們來通過一個小列子感受一下:

a = [1,2,3]nb = a nb.append(4)nprint(a)nnnOUT:n[1, 2, 3, 4]nn

變數a、b同時引用了同一個列表[1,2,3]

b並不是那個列表的拷貝。

為了更好地理解Python中的賦值語句,我們應該始終讀式子的右邊。對象再右邊創建或獲取,再次之後,才會綁定到左邊的變數上。這就像為對象貼上了「標註」,而不是用盒子把對象裝起來。

標識、相等性、別名

ehco = {name:ehco,age:21}nxiaozhou = ehconnprint(xiaozhou == ehco )nprint(xiaozhou is ehco)nprint(id(xiaozhou),id(ehco))nnfake_ehco = {name:ehco,age:21}nprint(fake_ehco==ehco)nprint(fake_ehco is ehco)nprint(id(fake_ehco),id(ehco))nnnnOUT:nTruenTruen4477069280 4477069280nnTruenFalsen4561643560 4561643488nn

在這裡,xiaozhou即為ehco的別名,我們通過id函數確認了:

xiaozhou和ehco實際上引用的是同一個字典對象:{name:ehco,age:21}

fake_ehco的值雖然和ehco一樣,

但實際上他們兩個是兩個獨立的對象

這是因為,每個變數都有標識,類型和值,對象一旦創建,他的標識絕對不會變,(標識積內存地址) 可以通過id函數來得到標識,而is函數則是比較對象之間的id是否相同。

比較時是用is還是==

這個問題其實很簡單。

當我們只關心變數的值的時候,我們用==

其他的時候,我們應該用is

默認為淺複製

複製列表(或者其他內置的可變集合)最簡單的方式是使用內置類型的構造方法。

而然這種複製是淺複製,如果元素都是不可變的,那麼沒有問題,但如果元素包含了可變類型,那麼結果可能就不是我們想要的了。

l1 = [1,2,3,[4,5]]nnl2 = list(l1) # 通過構造方法進行複製 nl2 = l1[:] #也可以這樣想寫nnnl2.append(9)nprint(l1: {} nl2: {}.format(l1,l2))nnl2[3].append(8)nprint(l1: {} nl2: {}.format(l1,l2))nnnnOUT:nnl1: [1, 2, 3, [4, 5]]nl2: [1, 2, 3, [4, 5], 9]nnl1: [1, 2, 3, [4, 5, 8]]nl2: [1, 2, 3, [4, 5, 8], 9]nn

可以看到,我們通過list的構造方法,十分便捷的複製了l1

通過第一個輸出,我們能看到l2和l2是兩個獨立的對象。

可通過第二個輸出,

我們明明沒有對l1進行操作,

可存在l1里的列表的值也更新了

這就是淺複製帶來的弊端了。

l1[3] 里寸的是另外一個列表的引用,

這是一個可變的對象,所以在進行複製操作時,

l1[2] 和 l1[3]內引用的對象是同一個。

那麼如何進行深度複製呢?

copy 模塊中的copy() 和 deepcopy() 函數

可以對任意對象進行淺複製和深度複製。

本章小結

本章著重說了:每個Python對象都有其標識,類型和值,但只有對象的值會發生改變。

每個對象唯一的身份id可以用其內存地址表示,用id函數就能獲取

關於可變類型和不可變類型我們通過幾個例子,有了更加深入的了解

在複製變數的時候,記住默認是淺複製。

這就引申到了下面幾點:

  • 函數的參數 (不要使用可變類型作為參數的默認值)
  • Python的垃圾回收機制 (這裡我也描述不好,有興趣可以查閱相關書籍)

每天的學習記錄都會 同步更新到:

微信公眾號: findyourownway

知乎專欄:zhuanlan.zhihu.com/zen-

Blog : www.ehcoblog.ml

Github: github.com/Ehco1996/


推薦閱讀:

python教程看完了,還是不會編程?
二廠開工——Fake Cuneiform
Python3《機器學習實戰》學習筆記(九):支持向量機實戰篇之再撕非線性SVM
【翻譯搬運】SciPy-Python科學演算法庫
pycham如何整合pyqt5並安裝qtdesigner?

TAG:Python |