首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python 深拷貝與淺拷貝徹底講解:變量-引用-對象模型、可變/不可變對象、切片、copy 模塊與性能基準

     編輯:更多程式設計知識

Python 拷貝機制是面試高頻考點,也是生產 Bug 溫床。本文從「變量-引用-對象」內存模型講起,系統梳理不可變對象共享安全、可變對象淺拷貝陷阱、深拷貝遞歸複製、切片行為、copy 模塊 API、自定義 __copy__/__deepcopy__、性能基準與最佳實踐,幫你建立不可動搖的心智模型。

核心內存模型:變量 ≠ 盒子,而是標籤

  • 變量:指向對象的引用(指針),存儲在棧/字典中。
  • 對象:堆上分配的實體,包含類型信息、引用計數、值。
  • 引用:變量到對象的映射,id(obj) 返回對象地址。

不可變對象:共享即安全

  • 數值、字符串、元組、frozenset、bytes 等。
  • 「修改」實則是創建新對象,原對象不變,共享引用無副作用。
  • Python 對小整數 [-5, 256]、短字符串進行駐留,相同值共享同一對象。

可變對象:淺拷貝只複製頂層

切片 [:] 是淺拷貝

  • 序列類型:list、tuple、str、bytes 支持切片。
  • tuple[:] 返回元組自身(不可變,無需複製)。
  • str[:] 返回字符串自身。
  • 字典不支持切片,用 dict.copy() 或 {**d}。

copy 模塊 API

自定義拷貝語義

性能基準(Python 3.11,100 萬次操作)

字典拷貝對比

決策流程圖:我該用哪種拷貝?

需要拷貝?
├─ 不可變對象 (int, str, tuple...) → 無需拷貝,直接賦值
└─ 可變對象
   ├─ 扁平 (無嵌套可變元素) → list() / [:] / dict.copy() / copy.copy()
   └─ 嵌套可變元素
      ├─ 需完全隔離 → copy.deepcopy()
      ├─ 性能敏感、結構固定 → 手寫專用拷貝函數 / pickle 往復
      └─ 循環引用 → copy.deepcopy() 自動處理 (memo 字典)

常見 Bug 現場

函數行為適用
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 代碼的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved