天天看點

Python之引用和共享引用

參考了《python學習手冊》這本書,還有在網上找的一些資料。分享一下,也算單個總結。

1.引用

看下面的例子:

a = 3
           

在開始學習python的時候,我的認識比較淺薄,單純的認為i這隻是一個簡單的指派語句。随着學習的深入。逐漸了解到。這一行代碼意味着什麼。

  • 先建立一個對象來代表3.
  • 再建立一個變量a
  • 将變量與新的對象3相連接配接。

這行代碼就算執行了。

那麼引用是什麼呢?

在python中從變量到對象的連接配接稱作引用。也就是,引用是一種關系,通過記憶體中的指針的形式來實作。具體的來說:

  • 變量是一個系統表的入口,包含了指向對象的連接配接。
  • 對象是被配置設定到的一塊記憶體,有足夠的空間去表示它們所代表的值。
  • 引用是自動形成的從變量到對象的指針。

注:我對引用比較形象的了解,寵物狗是具體的對象,名字就是變量。我建立一個變量,意味着取個名字。這個名字和寵物狗連接配接到了一起。每當我喊這個名字,那個狗就會響應我的呼喊。每當我使用這個變量,這個變量連接配接的對象也将為我所用。當然這隻能是我個人的了解,并不是那麼準确。

2.共享引用

看下面的例子

a = 3
b = a
a = 'spam'
           

我們還可以試下清單,集合等可變類型。

a = [1, 2, 3]
b = a
a = [4, 5, 6]
           

運作指派語句b=a 之後。變量b成為對象3的一個引用。在内部變量b實際上一個指針指向了對象的空間。這樣的,視為共享引用。因為變量a,和變量b都指向了對象3.

為了判斷這種情況,我們可以使用兩種方法,配合使用id()函數來列印它的記憶體位址。驗證這樣的執行情況。

注:id函數。傳回對象的“辨別”。這是一個整數(或長整數),保證該對象在其生命周期内是唯一且不變的。具有非重疊生存期的兩個對象可能具有相同的id()值。

還可以來個判斷第一種是“==運算符”。第二種“is”.is 判斷,可以判斷對象的同一性。它傳回一個布爾值,True或者是False。

print(a)
print(b)
print(id(a))
print(id(b))
print( a is b)
           

3.固定位址和臨時位址

在自己嘗試列印中,又發現一些有趣的現象。就是每一次列印的時候。列印的id是不一樣的。這就牽涉到另外一個概念。就是固定位址和臨時位址。這裡我接觸到一個python源碼的概念,叫做緩沖池。針對一些高頻常用的資料,有确定的記憶體位址,不會改變。

使用固定記憶體位址存儲資料如下:

-5到256的整數(小整數對象池)

True和False

由字母、數字、下滑線組成的字元串

使用臨時記憶體位址存儲資料如下:

小于-5後大于256的整數

所有小數

包含字母、數字、下滑線之外的字元組成的字元串

我們可以嘗試一下列印256 和257的id。多列印幾次,來驗證看看。

print(id(256))
print(id(257))
           

還有需要特别注意的是事情就是。

a = [1]
b = [1]
print(a is b)
           

執行上述代碼,傳回的是一個False。每當建立一個對象,python都會開辟一個新的記憶體空間。這樣了解,a is b就好了解了。當然。這樣說不是很準确。

a = tuple()
b = tupel()
print( a is b)
           

執行上述代碼,傳回的是一個True,所有的空元組共用一個記憶體位址。當然這個記憶體位址是臨時位址,它是變化的。

我查了比較多的資料。這個跟python内部的存儲機制有關系,

這裡貼出一個連結。是我在上網搜尋的。當然隻要你感興趣。都可以搜的到。

https://www.hongweipeng.com/index.php/archives/1630/

注:我們可以用到getsizeof()檢視記憶體大小,和getrefcount()檢視引用次數。幫助了解。

新手學習,請多多指教。