Python 拷貝機制是面試高頻考點,也是生產 Bug 溫床。本文從「變量-引用-對象」內存模型講起,系統梳理不可變對象共享安全、可變對象淺拷貝陷阱、深拷貝遞歸複製、切片行為、copy 模塊 API、自定義 __copy__/__deepcopy__、性能基準與最佳實踐,幫你建立不可動搖的心智模型。
id(obj) 返回對象地址。[:] 是淺拷貝list、tuple、str、bytes 支持切片。tuple[:] 返回元組自身(不可變,無需複製)。str[:] 返回字符串自身。dict.copy() 或 {**d}。| 函數 | 行為 | 適用 |
|---|---|---|
copy.copy(x) | 淺拷貝:新容器,元素共享引用 | 扁平列表/字典、自定義對象淺層複製 |
copy.deepcopy(x, memo={}) | 深拷貝:遞歸複製對象圖,處理循環引用 | 嵌套結構、複雜對象圖 |
| 代碼 | Bug | 修正 |
|---|---|---|
def f(a=[]): a.append(1) | 默認參數只計算一次,所有調用共享同一列表 | def f(a=None): a = a or [] |
matrix = [[0]*3]*3 | 外層列表包含 3 個指向同一內層列表的引用 | [[0]*3 for _ in range(3)] |
new_list = old_list | 以為複製了,實則共享 | new_list = old_list[:] |
copy.copy(nested_dict) | 嵌套字典修改影響原對象 | copy.deepcopy(nested_dict) |
Python 拷貝本質是「引用複製」vs「對象圖遞歸複製」。牢記:賦值不複製、切片淺複製、copy.copy 淺複製、copy.deepcopy 深複製。不可變對象無需拷貝;扁平可變對象用淺拷貝;嵌套可變對象必須深拷貝。性能敏感場景避免濫用 deepcopy,改用結構化拷貝或序列化往復。建立清晰的對象所有權意識,是寫出無副作用 Python 代碼的關鍵。