1. 程式人生 > >Python 語言學習 第四篇:動態型別模型

Python 語言學習 第四篇:動態型別模型

Python的變數不用宣告,賦值之後就可以直接使用,型別是在執行過程中自動確定的,這就是動態型別模型。該模型把變數和物件設計成兩個不同的實體,物件是儲存資料的地方,物件的型別是由初始值自動決定的,而變數僅僅是物件的引用。變數是通用的,同一個變數名可以引用任何型別的物件。

一,變數、物件和引用

動態型別模型由三部分構成:變數、物件和引用。變數和型別沒有任何關係,型別是物件的,變數只是引用物件而已。例如,a=3,a是變數名,Python自動建立一個記憶體物件,值是3,變數a自動引用物件。

1,變數

對於一個變數,當第一次給它賦值時,就建立了變數,並把變數關聯到記憶體物件。之後對變數的賦值,將會改變變數引用的物件。

從技術上來看,變數是指標型別,所謂的資料型別,是指變數引用的物件的型別,型別的概念存在於物件中,而不是變數中。

當變量出現在表示式中時,它會被當前引用的物件所代替,無論這個物件是什麼型別。

2,物件

從技術上講,物件是一塊記憶體空間,儲存頭部和內容。每個物件都有兩個標準的頭部資訊:一個型別標誌符用於標識物件的型別,一個計數器用於標識被應用的次數。當對用被引用的次數為0時,Python會自動回收該物件佔用的記憶體空間。

3,引用

變數和物件通過引用關聯在一起,在使用變數時,Python自動通過引用獲取或設定物件的值。

二,通用型別分類

Python的核心型別,通常細分為:整數、字串、元組、列表、字典,也可以按照操作分為整數、序列和對映,也可以按照物件是否支援原處修改,把型別分為可變型別和不可變型別。

1,按照操作分類

  • 整數是不可變的物件,支援算術運算;
  • 集合是無序的,支援集合操作;
  • 字串、列表和元組是序列,元素的位置是順序的,可以按照偏移對序列進行索引和分片操作;
  • 字典是對映,元素之間沒有順序,但是通過對映來獲取值,而不是通過偏移。

2,按照可變性分類

物件的可變性是指物件是否可以原處修改,原處修改是指物件的記憶體空間是否可以被修改。

Python的型別從可變性上可以分為兩類:可變型別和不可變型別,

  • 可變型別:列表、字典
  • 不可變型別: 整數,字串、元組,集合

可變物件可以在原處被修改,不可變物件一旦建立成功,就保持不變。

三,賦值和共享引用

在使用賦值符號(=)時,如果變數對變數“賦值”,產生共享引用,兩個變數引用同一個物件;如果是使用物件對變數賦值,產生的結果是建立新的物件,同時使變數引用新的物件。

例如,把變數賦值給變數時,變數之間存在共享引用,也就是說,多個變數名引用同一個物件,

a=3
b=a

此時,變數a和b同時指向一個物件。變數名賦值給變數名,使得兩個變數引用相同的物件。

當把物件賦值給變數時,並不是替換了原始的物件,而是讓這個變數去引用另一個完全不同的物件。

例如,當變數重新賦值時,a='abc',變數a引用的是另一處記憶體空間。此時,b是3,而a是abc。

a='abc'

1,共享引用和可原處修改

當共享引用的物件是可變型別時,對可變物件的修改,會反應到共享引用的變數上。

例如,變數l1和l2是共享引用,引用的物件是列表,而列表支援原處修改:

l1=[1,2,3]
l2=l1

當修改變數l1引用的物件的值時,變數l1和l2引用的還是同一個記憶體空間,l1和l2的值是相同的。

l1[0]=5

2,共享引用和相等

==和is是不同的“相等”比較,前者是指值相等,後者是指物件的同一性(同一個物件)。

例如,a和b既是值相等,也是物件同一的。

a=[1,2]
b=a

例如,a和b是值相等,但是物件不是同一個,這說明,可變型別的常量的快取是不可複用的。

a=[1,2]
b=[1,2]

例如,x和y既是值相等,也是物件同一的,這說明,不可變型別的常量的快取是複用的。

x=1
y=1

四,深拷貝和淺拷貝

淺拷貝是指引用的拷貝,深拷貝是指物件的拷貝。在Python中,淺拷貝存在於下面三種情況:

  • 共享引用是淺拷貝,兩個變數引用同一個物件。
  • 由於Python會複用不可變物件,因此,不可變物件的賦值都是淺拷貝。
  • 賦值生成的是淺拷貝。

深拷貝是指值相同的不同物件,因此,== 運算的結果是True,而 i s運算的結果是False,例如,a和b的值相同,但是引用的物件不同。

a=[1,2]
b=[1,2]

對a進行修改,不會引用b的值,列表的深拷貝,也可以通過list.copy()函式來實現。

>>> a=[1,2]
>>> b=a.copy()
>>> a==b
True
>>> a is b
False 

對於可變型別的深拷貝:

  • 列表型別有:list.copy(),list[:],list(list_var)
  • 字典型別:dict.copy()
  • copy標準庫模組中
import copy
x=copy.deepcopy(y)

 

參考文件: