目錄
重點::
- Python只有一種 assignment model,就是動態的 variable+object+reference模型
- 類型信息是跟object有關的,而variable可以引用任何object
- Python本身會緩存小的int和string數據
- 避免 in-place改變,需要提前copy
- 判斷相等的方法有2種:
==
和is
Chap6 動態類型
6.1 無需聲明類型
Python自己有一個dynamic typing model
. 類型是在runtime時候決定的。
6.1.1 Variable, Object, Reference
- 變量創建:直接賦值。Technically,Python detects some names before your code runs, but you can think of it as thoughinitial assignments make variables.
- 變量類型:變量本身不包含類型信息,信息包含在objects內
- 使用變量:當變量出現在表達式中時,它馬上被替換成了實際的object來使用
a. 創建對象時的步驟
a = 3
- 創建一個表示3的對象
- 創建變量a
- 將a的引用指向這個對象3
雖然實際上, python爲了優化,在內部會緩存和重用一些不變的對象,比如小的int和 string。
6.1.2 類型和objects有關,而不是variable
每個對象至少有2個標準的頭部信息:
- type designator 來表示類型信息
- reference counter 爲了垃圾回收
實際上來說,這個type designator
是一個指向實際類型對象的指針,比如int類型的對象,那麼這個type designator
就是一個指向int object
的指針。
6.1.3 垃圾回收
對象內部當 reference counter
的指針爲0的時候,就會被python的GC回收。
除了這個reference counter, python的 gc內部還有一個組件能夠偵察循環引用的問題。
6.2 Shared Reference
上面這張圖,就叫做shared reference.
6.2.1 Shared References and In-Place Changes
>>> L1 = [2, 3, 4] # A mutable object
>>> L2 = L1 # Make a reference to the same object
>>> L1[0] = 24 # An in-place change
爲了避免inplace change 的影響,應該提前複製:
- 使用list函數創建一個新的:
old = list(new)
- 切片
- 對象.copy() 方法
copy
模塊的copy
和deepcopy
方法
6.2.2 Shared References and Equality
>>> x = 42
>>> x = 'shrubbery' # Reclaim 42 now?
因爲python會緩存小的int還有 string, 所以上面的42並不會被垃圾回收,而是在system table中,等待下次使用的時候調用;而其他大部分objects,都會在沒有被引用之後立馬被回收掉。
- Python內2種比較的方法:
- a == B : 值比較
- a is B : 引用比較
>>> L = [1, 2, 3]
>>> M = L # M and L reference the same object
>>> L == M # Same values
True
>>> L is M # Same objects
True
>>> L = [1, 2, 3]
>>> M = [1, 2, 3] # M and L reference different objects
>>> L == M # Same values
True
>>> L is M # Different objects
False
# 被緩存的數字的比較
>>> X = 42
>>> Y = 42 # Should be two different objects
>>> X == Y
True
>>> X is Y # Same object anyhow: caching at work!
True
可以使用下面的方法來查看object有幾個引用:
>>> import sys
>>> sys.getrefcount(1) # 647 pointers to this shared piece of memory
647