在 Python 中,淺拷貝(Shallow Copy) 和 深拷貝(Deep Copy) 是處理對象復制的兩種重要機制,它們的區別主要體現在對嵌套對象的處理方式上。以下是詳細解析:
1. 淺拷貝(Shallow Copy)
淺拷貝會創建一個新對象,但新對象中的子對象是原對象中子對象的引用。
特點:
- 只復制外層對象,嵌套對象(如列表中的列表、字典中的字典)仍與原對象共享。
- 修改淺拷貝的外層對象不會影響原對象,但修改嵌套對象會同時影響原對象和淺拷貝。
實現方式:
- 使用
copy
模塊的copy()
方法。 - 對列表使用切片操作
new_list = old_list[:]
。 - 對字典使用
dict.copy()
方法。
示例:
import copyoriginal = [[1, 2, 3], [4, 5, 6]]
shallow_copy = copy.copy(original)# 修改外層對象
shallow_copy.append([7, 8, 9])
print(original) # [[1, 2, 3], [4, 5, 6]](原對象未改變)
print(shallow_copy) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]# 修改嵌套對象
shallow_copy[0][0] = 100
print(original) # [[100, 2, 3], [4, 5, 6]](原對象被修改!)
print(shallow_copy) # [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
2. 深拷貝(Deep Copy)
深拷貝會遞歸地復制所有嵌套對象,完全獨立于原對象。
特點:
- 新對象和原對象的所有層級完全獨立,修改任一對象均不會影響另一個。
- 適用于需要完全隔離的場景,但性能開銷較大(尤其是大型嵌套對象)。
實現方式:
- 使用
copy
模塊的deepcopy()
方法。
示例:
import copyoriginal = [[1, 2, 3], [4, 5, 6]]
deep_copy = copy.deepcopy(original)# 修改嵌套對象
deep_copy[0][0] = 100
print(original) # [[1, 2, 3], [4, 5, 6]](原對象未被修改)
print(deep_copy) # [[100, 2, 3], [4, 5, 6]]
3. 核心區別
特性 | 淺拷貝 | 深拷貝 |
---|---|---|
復制層級 | 僅外層對象 | 遞歸復制所有嵌套對象 |
內存占用 | 低 | 高(遞歸復制所有對象) |
修改嵌套對象 | 影響原對象 | 不影響原對象 |
性能 | 快 | 慢(尤其是復雜結構) |
4. 使用場景
- 淺拷貝:適用于簡單對象(如單層列表、字典),或允許共享嵌套對象的場景。
- 深拷貝:適用于需要完全獨立的復雜嵌套對象(如多層結構、類實例)。
5. 注意事項
- 不可變對象(如字符串、元組、數字)的拷貝沒有實際意義,因為它們不可修改。
- 自定義對象的拷貝需要實現
__copy__()
和__deepcopy__()
方法以控制拷貝行為。 - 嵌套對象中如果包含循環引用(如對象 A 包含對象 B,對象 B 又引用對象 A),深拷貝可能引發遞歸錯誤。
6. 總結
- 淺拷貝是“表層復制”,適合簡單場景;深拷貝是“完全獨立復制”,適合復雜嵌套場景。
- 選擇拷貝方式時,需根據數據結構和需求權衡性能與獨立性。