1. 標識、相等性和別名
變量a和b是否是同一個值的引用, 可以用 is 來進行判斷:
>>> a = b = [4,5,6]
>>> c = [4,5,6]
>>> a is b
True
>>> x is c
False
如果兩個變量都是指向同一個對象, 我們通常會說變量是另一個變量的 別名 .
在==和is之間選擇
運算符 == 是用來判斷兩個對象的值是否相等(注意是對象值). 而 is 則是用於判斷兩個變量是否指向同一個對象, 或者說判斷變量是不是同一個別名, is 並不關心對象的值. 從使用上, == 使用比較多, 而 is 的執行速度比較快.
2. 淺拷貝深拷貝
淺拷貝:拷貝出的新的對象,並引用源對象的一切
>>> import copy
>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> a,b,
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].remove(3)
>>> a,b
({1: [1, 2]}, {1: [1, 2]})
>>>
深拷貝:遞歸地拷貝源對象中的一切。(徹頭徹尾的另立門戶)
>>> import copy
>>> c = copy.deepcopy(a)
>>> a,c
({1: [1, 2]}, {1: [1, 2]})
>>> a[1].append(3)
>>> a,c
({1: [1, 2, 3]}, {1: [1, 2]})
>>>
3. 函數的參數做引用時
python中的函數參數都是採用共享傳參. 共享傳參指函數的各個形式參數獲得實參中各個引用的副本. 也就是說, 函數內部的形參
是實參的別名.
傳入不可變對象無法修改外部的值
>>> def f(a, b):
... a += b
... return a
...
>>> x = 1
>>> y = 2
>>> f(x, y)
3
>>> x, y
(1, 2)
>>> t = (10, 20)
>>> u = (30, 40)
>>> f(t, u)
(10, 20, 30, 40)
>>> t, u
((10, 20), (30, 40))
傳入可變對象可以修改外部的值
>>> a = [1, 2]
>>> b = [3, 4]
>>> f(a, b)
[1, 2, 3, 4]
>>> a, b
([1, 2, 3, 4], [3, 4])
4. 不要使用可變對象作爲函數的默認值
參數默認值是個很棒的特性. 對於開發者來說, 應該避免使用可變對象作爲參數默認值. 因爲如果參數默認值是可變對象, 而且修改了它的內容, 那麼後續的函數調用上都會收到影響,最好是將默認值設爲None。
>>> def f(v,l=[]):
l.append(v)
print(id(l))
return l
>>> f('a')
70125408
['a']
>>> f('b')
70125408
['a', 'b']
>>>
這種結果應該不是你想要的。爲了避免這種情況的發生,最好是將默認值設爲None,然後在函數裏面檢查它,
>>> def f(v, l=None):
if l is None:
l = []
l.append(v)
print(id(l))
return l
>>> f('a')
70125808
['a']
>>> f('b')
70124808
['b']
>>>
5. del 和垃圾回收
del 語句刪除名稱,而不是對象。 del 命令可能會導致對象被當作垃圾回收,但是僅當刪除
的變量保存的是對象的最後一個引用,或者無法得到對象時。 2 重新綁定也可能會導致對象
的引用數量歸零,導致對象被銷燬。