Python 淺複製的特性還是缺陷?

2021-09-10 15:55:02 字數 2550 閱讀 3041

我們首先來看官方對列表/字典中copy方法的描述:

>>> help(dict.copy)

help on method_descriptor:

copy(...)

d.copy() -> a shallow copy of d

>>>

>>> help(list.copy)

help on method_descriptor:

copy(...)

l.copy() -> list -- a shallow copy of l

那麼,我們建立乙個dict_instance物件,再用copy_instance來接受對dict_instance淺複製的返回結果:

>>> dict_instance =

>>> copy_instance = dict_instance.copy()

>>> dict_instance[0][0] = 1

>>> dict_instance

>>> copy_instance

上述,我們修改了字典物件的「0」鍵所指代的列表值的第乙個元素為1,即dict_instance[0][0] = 1,顯然copy_instance跟隨了這樣的修改。可以自行使用id函式看到,確實copy實現了這樣的淺複製。

到目前為止,copy都是正常工作,也符合我們的預期。從一開始,我便希望淺複製時刻保持位址的一致性,但python的淺複製(不論是copy.copy、list.copy還是dict.copy)是否能夠時刻保持位址的一致性呢?

>>> from copy import copy

>>> list_instance = [1, 2, 3]

>>> copy_instance = copy(list_instance)

>>> [id(x) for x in list_instance]

[1386622096, 1386622112, 1386622128]

>>> [id(x) for x in copy_instance]

[1386622096, 1386622112, 1386622128]

>>> list_instance[0] = 4

>>> list_instance

[4, 2, 3]

>>> copy_instance

[1, 2, 3]

>>> [id(x) for x in list_instance]

[1386622144, 1386622112, 1386622128]

>>> [id(x) for x in copy_instance]

[1386622096, 1386622112, 1386622128]

>>> list_copy = list_instance.copy()

>>> list_instance

[4, 2, 3]

>>> list_copy

[4, 2, 3]

>>> [id(x) for x in list_instance]

[1386622144, 1386622112, 1386622128]

>>> [id(x) for x in list_copy]

[1386622144, 1386622112, 1386622128]

>>> list_instance[0] = 0

>>> list_instance

[0, 2, 3]

>>> list_copy

[4, 2, 3]

>>> dict_instance =

>>> dict_copy = dict_instance.copy()

>>> [id(x) for x in dict_instance]

[1386622080, 1386622096, 1386622112]

>>> [id(x) for x in dict_copy]

[1386622080, 1386622096, 1386622112]

>>> dict_instance[0] = 3

>>> dict_copy

可以明顯地觀察到,列表和字典自帶的copy方法與copy.copy表現地一致,均沒有在」修改「不可變元素後繼續保持一致

這與我的預期相悖:從我的邏輯上來說,既然是淺複製,且是python這門貼近人類自然邏輯的語言,它們應當時刻保持位址一致性,對程式設計人員遮蔽所有破壞位址一致性的操作,強制保持一致。但事實結果已經在上文闡述了。

我無法說清這是否是這門語言的特性,但這確確實實會造成對**理解的二義性,事實上我和我的朋友就在前幾日程式設計時便錯誤解讀了淺複製的這種特性,甚至因這種特性混淆了深淺複製的概念,於是我認為它應該是一種邏輯缺陷,但如果要彌補缺陷,又會造成新的問題諸如相容性,為考慮這種情形需要新增的分支判斷,修改原有執行機制等,這是乙個值得思考的問題。

Python 深淺複製

python中的賦值語句不複製物件,它們在目標和物件之間建立繫結。對於可變的或包含可變項的容器,有時需要乙個副本,所以可以改變乙個副本而不改變另乙個。將建立乙個新物件,但它包含的是對原始物件包含的項的引用。a b list a c a.copy d copy.copy a 建立乙個新物件,並且遞迴的...

python 深複製和淺複製

l1 1,2,3 4,5 l2 list l1 l1 1,2,3 4,5 99 l2 1,2,3 4,5 l1 1 remove 2 l1 1,3 4,5 99 l2 1,3 4,5 l2 1 11,12 l2 2 10,11 l1 1,3,11,12 4,5 99 l2 1,3,11,12 4,5...

Python中的深淺複製

最近遇到了乙個問題,在python中對於物件的複製有兩種,copy 以及deepcopy 為了研究他們之間的區別,寫下如下部落格。首先檢視python的官方文件,得到如下解釋 淺層複製和深層複製之間的區別僅與復合物件 即包含其他物件的物件,如列表或類的例項 相關 乙個 淺層複製 會構造乙個新的復合物...