我在 Python 里拷贝了一个嵌套列表,以为是独立副本,结果改副本的内层元素原列表也跟着变了,我对着浅拷贝只复制一层排查了大半天的复盘

我有个嵌套列表(列表套列表),想要份独立副本来改、不影响原始数据,顺手用了切片 original

我在 Python 里拷贝了一个嵌套列表,以为是独立副本,结果改副本的内层元素原列表也跟着变了,我对着浅拷贝只复制一层排查了大半天的复盘

这是一个让我对 Python 的"深拷贝 vs 浅拷贝"刻骨铭心的故事。我有个嵌套的数据结构(列表里套着列表,类似一个二维表),我想要一份独立的副本来修改,而不影响原始数据。我顺手用了切片 copy = original[:](也试过 list(original)copy.copy()),心想"这就拷贝出一份独立的了"。可当我修改这个副本里的内层元素时,诡异的事发生了:只改了副本,可原始的那个列表,内层的数据,也跟着一起变了!我明明拷贝了一份,为什么改副本会影响到原件?这"副本",好像只独立了一半

我顺着"改副本影响原件"的线索深挖,才终于揭开真相,补上了我对 Python 一个最基础、却极易踩的认知漏洞:问题的核心,是我做的是"浅拷贝(shallow copy)",而它只复制了"最外层"。我一直想当然地以为,"拷贝就是把整个东西完整复制一份,从里到外都独立";可真相是:original[:] / list(original) / copy.copy() 这些,都是"浅拷贝"——它复制了最外层那个容器(创建了一个新的外层列表),而这个新列表里装的每一个内层元素,仍然是和原列表共享的、同一个对象的引用!换句话说:外层是"新的",但内层,还是"原来那些";新旧两个外层列表,指向的是同一批内层对象所以:当我改副本里的内层元素(比如 copy[0].append(x)copy[0][1] = y)时,因为 copy[0] 和 original[0] 本就是同一个内层列表,所以原列表的内层,自然也跟着变了(而如果我替换整个外层元素,比如 copy[0] = newList,那只动了副本的外层,原件不受影响——这也印证了"只有外层是独立的"。)我这才痛彻地明白:Python 的拷贝,有""和""之分;浅拷贝,只复制一层,内层对象仍是共享的引用;对于嵌套的数据结构,浅拷贝得到的,不是一个"完全独立"的副本,而是一个"外层独立、内层共享"的"半成品";用它来"隔离修改",会在你改动内层时,意外地"串改"了原始数据。要得到一份真正完全独立的副本,必须用 copy.deepcopy()——它会递归地、把每一层都复制一遍,让新旧之间,再无任何共享

故障现场:浅拷贝只复制外层,内层仍共享

我把这个"改副本影响原件"的现场,摊开给你看:

# ✗ 灾难: 浅拷贝只复制外层, 内层元素仍和原对象共享
original = [[1, 2], [3, 4]]    # 嵌套列表: 外层 list, 里面装着两个内层 list

# 几种常见的"浅拷贝"(都只复制最外层):
copy1 = original[:]            # 切片浅拷贝
copy2 = list(original)         # list() 浅拷贝
import copy
copy3 = copy.copy(original)    # copy.copy() 浅拷贝

# ✗ 改副本的"内层元素", 原对象也跟着变!
copy1[0].append(99)           # 改 copy1 的第0个内层 list
print(original)               # ✗ [[1, 2, 99], [3, 4]] —— 原对象的内层也变了!
copy1[1][0] = 100
print(original)               # ✗ [[1, 2, 99], [100, 4]] —— 又串改了!

# 为什么? 浅拷贝只复制了"外层容器", 内层是共享引用:
#   - copy1 是一个"新的外层 list"(和 original 不是同一个外层)。
#   - 但 copy1[0] 和 original[0] 是"同一个内层 list"(共享引用!)。
#   - 所以改 copy1[0] 的内容 = 改 original[0] 的内容。
#   验证: print(copy1[0] is original[0])  → True(同一个对象!)

# 对比: 只改"外层"(替换整个元素)不影响原件
copy1[0] = [7, 8]            # 替换整个外层元素(让 copy1[0] 指向新 list)
print(original[0])           # [1, 2, 99] —— 这次原件没变(只改了副本外层指向)
#   → 印证: 浅拷贝"外层独立, 内层共享"。

# 同样的坑: dict 浅拷贝
d = {"a": [1, 2]}
d2 = d.copy()                # 浅拷贝
d2["a"].append(3)
print(d)                     # ✗ {"a": [1, 2, 3]} —— 内层 list 共享, 原 dict 也变!

# 根因: 浅拷贝(切片/list()/copy.copy/dict.copy)只复制最外层容器,
#   内层嵌套对象仍是共享引用; 改内层就串改了原对象。

看着这段"改副本却串改了原件"的代码,我才算彻底想明白了根源。问题的核心,是浅拷贝只复制了"外层容器",内层是共享引用copy1 = original[:] 之后:copy1 是一个"新的外层 list"(和 original 不是同一个外层),但 copy1[0]original[0] 是"同一个内层 list"(共享引用!);所以copy1[0] 的内容,就等于改 original[0] 的内容(copy1[0] is original[0]True)。只改"外层"(替换整个元素 copy1[0] = [7,8])就不影响原件——恰恰印证了"浅拷贝外层独立、内层共享"同样的坑也出现在 dict.copy():浅拷贝 dict 后,改内层的 list,原 dict 也跟着变归根结底:浅拷贝(切片/list()/copy.copy/dict.copy)只复制最外层容器,内层嵌套对象仍是共享引用;改内层就串改了原对象——这,就是根源。

第一件事:搞懂深拷贝与浅拷贝

定位到根源,我必须把"深拷贝 vs 浅拷贝"从根上彻底搞清楚:

浅拷贝只复制最外层(内层共享引用); 深拷贝递归复制每一层(完全独立)

# 三个层次的"复制":
# 1. 赋值 b = a: 根本没复制! a 和 b 是同一个对象(同一引用)。
#    - 改 b 就是改 a(它们是一个东西)。
# 2. 浅拷贝(shallow): 复制"最外层容器", 内层元素仍是共享引用。
#    - 外层独立(新容器), 内层共享(同一批内层对象)。
#    - 改内层 → 影响原对象; 替换外层元素 → 不影响。
# 3. 深拷贝(deep): 递归复制"每一层", 新旧完全独立, 无任何共享。
#    - 改新对象的任何层, 都不影响原对象。

# 哪些是浅拷贝?
#   - 切片 a[:]、list(a)、dict(a)、set(a)、a.copy()、copy.copy(a)。
#   - 列表推导 [x for x in a](也是浅, 元素还是原引用)。

# 深拷贝怎么做?
#   - copy.deepcopy(a): 递归复制所有层级。

# 关键: 只有"嵌套了可变对象"时, 深浅拷贝才有区别!
#   - 扁平的、只含不可变元素的(如 [1,2,3]、["a","b"]): 浅拷贝就够(改不了内层元素本身)。
#   - 嵌套了 list/dict/对象 的: 必须深拷贝才能完全隔离。

# 为什么不总是用 deepcopy?
#   - deepcopy 递归复制, 慢、占内存(大结构开销大)。
#   - 有循环引用时要小心(deepcopy 能处理, 但要注意)。
#   - 按需选: 只含不可变 → 浅拷贝; 嵌套可变且要完全隔离 → 深拷贝。

# 关键认知: "拷贝"不是非黑即白, 要分清"复制了几层"。
#   - 想隔离修改, 先问: 我的数据有嵌套的可变对象吗? 有就要 deepcopy。

# 核心: 赋值=不复制, 浅拷贝=只复制外层(内层共享), 深拷贝=递归复制全独立;
#   嵌套可变对象要完全隔离必须 deepcopy; 扁平不可变浅拷贝即可。

原理终于清晰了。三个层次的"复制":① 赋值 b = a(根本没复制!a 和 b 是同一个对象,改 b 就是改 a);② 浅拷贝(复制"最外层容器",内层元素仍是共享引用——外层独立、内层共享;改内层影响原对象、替换外层元素不影响);③ 深拷贝(递归复制"每一层",新旧完全独立、无任何共享)。哪些是浅拷贝?切片 a[:]list(a)dict(a)a.copy()copy.copy(a)、列表推导深拷贝用 copy.deepcopy(a)关键:只有"嵌套了可变对象"时,深浅拷贝才有区别——扁平的、只含不可变元素的(如 [1,2,3])浅拷贝就够;嵌套了 list/dict/对象的,必须深拷贝才能完全隔离为什么不总是用 deepcopy?它递归复制、慢、占内存(大结构开销大),有循环引用要小心;按需选——只含不可变用浅拷贝,嵌套可变且要完全隔离才用深拷贝由此,我刻下一个关键认知:"拷贝"不是非黑即白,要分清"复制了几层";想隔离修改,先问"我的数据有嵌套的可变对象吗?有就要 deepcopy"。归根结底:赋值=不复制,浅拷贝=只复制外层(内层共享),深拷贝=递归复制全独立;嵌套可变对象要完全隔离必须 deepcopy;扁平不可变浅拷贝即可。

第二件事:正解——嵌套要完全隔离就用 deepcopy

搞懂了原理,正解就清晰了:嵌套了可变对象、且要完全隔离,就用 copy.deepcopy();扁平/只含不可变的,浅拷贝就够

import copy

# ✓ 正解一: 嵌套结构要完全独立, 用 deepcopy(递归复制每一层)
original = [[1, 2], [3, 4]]
deep = copy.deepcopy(original)   # ✓ 深拷贝, 每一层都是新的
deep[0].append(99)               # 改副本内层
print(original)                  # ✓ [[1, 2], [3, 4]] —— 原对象纹丝不动!
print(deep[0] is original[0])    # ✓ False(不是同一个内层对象了)

# ✓ 正解二: 扁平/只含不可变元素的, 浅拷贝就够(省开销)
flat = [1, 2, 3]
c = flat[:]                      # ✓ 浅拷贝足矣(int 不可变, 没有"改内层"一说)
c.append(4)
print(flat)                      # [1, 2, 3] —— 不受影响

# ✓ 正解三: 手动重建嵌套(可控, 也避免 deepcopy 开销)
matrix = [[1, 2], [3, 4]]
rebuilt = [row[:] for row in matrix]   # ✓ 对每个内层也做拷贝(两层都新)
rebuilt[0].append(99)
print(matrix)                    # [[1, 2], [3, 4]] —— 不受影响

# ✓ 正解四: 用不可变结构, 从根上避免"被改"
point = (1, 2)                   # tuple 不可变, 天然安全(没法改它)
from dataclasses import dataclass
@dataclass(frozen=True)          # 不可变 dataclass
class Config:
    name: str

# 决策:
#   - 嵌套了 list/dict/对象 + 要完全隔离 → copy.deepcopy。
#   - 扁平 + 只含不可变(数字/字符串/元组)→ 浅拷贝(切片/list())即可。
#   - 性能敏感的大结构 → 手动按需重建需要拷贝的部分, 避免全量 deepcopy。
#   - 能用不可变结构(tuple/frozen dataclass)→ 优先, 从根上避免误改。

# ⚠ deepcopy 的注意:
#   - 慢/占内存(大结构), 别滥用; 含外部资源(文件句柄/连接)的对象别 deepcopy。

# 核心: 嵌套可变+要完全隔离用 copy.deepcopy; 扁平不可变浅拷贝即可;
#   性能敏感按需重建; 能用不可变结构就用, 从根上免去拷贝烦恼。

修复的方向,核心是"按数据结构选对拷贝深度"正解一,嵌套结构要完全独立用 copy.deepcopy():它递归复制每一层,deep[0]original[0] 不再是同一个对象,改副本内层,原对象纹丝不动正解二,扁平/只含不可变元素的,浅拷贝就够(int 不可变,没有"改内层"一说,浅拷贝省开销)。正解三,手动重建嵌套([row[:] for row in matrix] 对每个内层也拷贝、两层都新,可控且避免 deepcopy 全量开销)。正解四,用不可变结构从根上避免"被改"(tuple 不可变天然安全、frozen dataclass 不可变)。决策上:嵌套可变+要完全隔离用 deepcopy;扁平+只含不可变用浅拷贝;性能敏感的大结构按需重建;能用不可变结构(tuple/frozen)就优先用(注意:deepcopy 慢/占内存,别滥用;含文件句柄/连接等外部资源的对象别 deepcopy。)归根结底:嵌套可变+要完全隔离用 copy.deepcopy;扁平不可变浅拷贝即可;性能敏感按需重建;能用不可变结构就用,从根上免去拷贝烦恼。

第三件事:深浅拷贝在真实场景里的坑

这次踩坑后,我把深浅拷贝在真实项目里容易翻车的场景,系统梳理了一遍:

# 深浅拷贝在真实场景里的坑:

# 1. 默认配置/模板被"串改"
default_config = {"options": {"retry": 3}}
def make_config():
    cfg = default_config.copy()      # ✗ 浅拷贝! options 还是共享的
    cfg["options"]["retry"] = 5      # ✗ 把 default_config 也改了!
    return cfg
#   → 之后所有用 default_config 的都被污染。要 deepcopy。

# 2. 把对象传给函数, 函数内"以为改的是副本"
def process(data):
    data["items"].append(x)          # ✗ 改的是调用方传进来的原对象的内层!
#   → 需要隔离就在函数内 deepcopy, 或约定不修改入参。

# 3. 缓存返回了"共享的可变对象"
cache = {"users": [...]}
def get_users(): return cache["users"]   # ✗ 返回的是缓存里的同一个 list!
#   调用方改了它 → 缓存被污染。→ 返回 deepcopy 或不可变副本。

# 4. 类的可变默认属性被多实例共享(类似可变默认参数)
class Box:
    items = []                       # ✗ 类属性! 所有实例共享同一个 list
#   → 用 __init__ 里 self.items = [] (实例属性)。

# 5. 浅拷贝以为安全, 嵌套层级深了才暴露
#   - data[:] 看着拷了, 但 data[0][1] 这种第二层改动会串。

# 排查技巧: 用 is 看是不是同一对象, id() 看地址。
#   print(copy[0] is original[0])  # True=共享(浅), False=独立(深)。

# 核心: 深浅拷贝坑常见于 默认配置被串改、函数改了传入对象内层、
#   缓存返回共享可变对象、类可变属性共享; 要隔离就 deepcopy 或返回不可变。

原来深浅拷贝的坑,处处潜伏默认配置/模板被串改(default_config.copy() 浅拷贝后改内层,把默认配置也污染了,之后所有人都被影响——要 deepcopy);把对象传给函数、函数改了它的内层(改的是调用方的原对象,需要隔离就在函数内 deepcopy);缓存返回了共享的可变对象(get_users() 返回缓存里的同一个 list,调用方一改缓存就被污染——返回 deepcopy 或不可变副本);类的可变默认属性被多实例共享(items = [] 是类属性、所有实例共享,要在 __init__ 里设实例属性);浅拷贝在层级深了才暴露排查技巧:is 看是不是同一对象、id() 看地址(copy[0] is original[0] 为 True 就是共享)。它们的共同根源,都是"以为拷了独立副本、实则内层还共享"。归根结底:深浅拷贝坑常见于默认配置被串改、函数改了传入对象内层、缓存返回共享可变对象、类可变属性共享;要隔离就 deepcopy 或返回不可变。

下面这张图,是这次"改副本影响原件"的成因与解法:

第四件事:赋值、浅拷贝、深拷贝速查对照

这次踩坑后,我把赋值、浅拷贝、深拷贝的区别,整理成一张速查表,以后拷贝前心里就有数了。

方式 复制了什么 改外层影响原件? 改内层影响原件?
b = a(赋值) 什么都没复制(同一对象) ✗ 影响(就是同一个) ✗ 影响
a[:] / list(a)(浅) 最外层容器 ✓ 不影响 ✗ 影响(内层共享)
copy.copy(a)(浅) 最外层容器 ✓ 不影响 ✗ 影响
copy.deepcopy(a)(深) 递归每一层 ✓ 不影响 ✓ 不影响
[row[:] for row in a](手动两层) 外层+一层内层 ✓ 不影响 ✓ 不影响(仅限两层)

这张表,把三种"复制"的差别讲透了。关键看最后两列——"改外层"和"改内层"是否影响原件:赋值两者都影响(根本是同一个);浅拷贝"改外层不影响、改内层影响"(外层独立、内层共享,这正是本文的坑);深拷贝两者都不影响(完全独立)。记住这个区分的实用价值:你能一眼判断"我这次拷贝,改了之后会不会串到原件"——只改外层?浅拷贝够;要改内层、且不想影响原件?必须深拷贝(或手动重建到对应层)它给我的启发是:"拷贝"这个看似简单的操作,其实有"复制几层"的深度维度;而 Python(以及很多语言)默认提供的拷贝,往往是""的——不会替你递归到底,需要深拷贝时,你得显式地要求(deepcopy)理解了"拷贝有深浅",并养成"拷贝嵌套结构前,先想清楚要拷几层"的习惯,就能避开这一整类"改了副本却串改原件"的隐蔽 bug

第五件事:这些"共享可变状态"的坑同根同源

这次浅拷贝的坑,本质是"意外地共享了可变状态"。顺着这个本质,我把 Python 里其他同源的坑梳理了一遍。

意外共享了什么 正解
浅拷贝嵌套结构 内层对象被新旧容器共享 deepcopy / 手动重建(本文)
可变默认参数 def f(x=[]) 默认 list 被多次调用共享 默认 None, 函数内再建
[[0]*3]*3 建二维 三行是同一个 list [[0]*3 for _ in range(3)]
类可变属性(类级 list) 所有实例共享同一个 __init__ 里设实例属性
b = a 赋值"复制" b 和 a 是同一对象 需要副本就 copy/deepcopy
函数返回内部可变对象 调用方拿到的能改到内部 返回拷贝或不可变

这张表,让我看清了这些坑共同的根它们本质上是同一个问题:以为有了几个"独立"的东西,实际它们却共享着同一个可变对象;于是改其中一个,意外地"串改"了其他的无论是浅拷贝(内层共享)、可变默认参数(默认对象共享)、[[0]*3]*3(三行共享)、类可变属性(实例共享)、赋值(同一对象)、函数返回内部可变对象(内外共享)——它们的病根,都是"在你以为是独立副本的地方,其实是共享引用";它们的解药,也都指向同一件事:当你需要"独立"时,就要显式地、彻底地创建一份新的(deepcopy/重建/返回不可变),而不能依赖"看起来像复制"的操作它给我的最大启发是:Python(以及很多语言)里,"引用共享"是默认,"独立副本"才需要你主动争取;而"意外的共享可变状态",是一整类极其隐蔽 bug 的总源头——它不报错,只是悄悄地让"改 A 串到 B"。所以,处理可变数据时,要时刻有一根弦:"我现在操作的,是一个'独立的副本',还是一个'和别处共享的引用'?如果我改它,会不会意外地影响到别的地方?"——这根弦绷紧了,这一整类"串改"的坑,就都能避开。

第六件事:要拷贝一个数据时,我现在会怎么决策

现在,每当我要拷贝一个数据结构,脑子里都会过一遍这张决策图——核心两问:它嵌套了可变对象吗?我要改哪一层?

这张图的灵魂,是拷贝前的两个必问第一问:它嵌套了可变对象吗?——没有(扁平且只含不可变),浅拷贝即可;有嵌套可变,再追问第二问。第二问:我会修改内层吗?——只读不改,浅拷贝甚至直接用都行;要改内层、且不能影响原件,就需要更深的拷贝需要深拷贝时按性能选:不敏感用 copy.deepcopy(最省心);敏感/大结构则手动重建需要拷贝的那几层最后,两个收尾的好习惯:能用不可变结构(tuple/frozen)就用,从根上免去拷贝烦恼;否则用 is/id 验证副本确实独立这套判断,让我拷贝数据时,不再"随手 [:] 就以为独立了"——核心始终是:看清它嵌套了几层可变对象,要改到哪层,就拷到哪层。

我立下的几条规矩

这场"改副本串改原件"的事故,换来了我写 Python 时,刻进骨子里的几条铁律:

  1. 浅拷贝只复制最外层,内层共享引用。切片/list()/copy.copy/dict.copy 都是浅拷贝,改内层会串改原件。
  2. 嵌套可变要完全隔离,用 copy.deepcopy。它递归复制每一层,新旧完全独立。
  3. 扁平/只含不可变的,浅拷贝就够。别滥用 deepcopy(慢、占内存);按数据结构选拷贝深度。
  4. 默认配置/缓存/函数入参,警惕浅拷贝串改。要隔离就 deepcopy 或返回不可变副本。
  5. 能用不可变结构就用。tuple、frozen dataclass 天然不会被改,从根上避免拷贝烦恼。
  6. 拿不准就用 is/id 验证。copy[0] is original[0] 为 True 就是共享(浅),False 才是独立(深)。
  7. 时刻分清"独立副本"和"共享引用"。改它前问一句:会不会意外影响到别处?

附:几行代码用 id() 看清浅拷贝的"假独立"

口说无凭。下面这几段,用 id()is 亲眼看清浅拷贝"外层独立、内层共享"的真面目,跑一遍胜过千言:

import copy

original = [[1, 2], [3, 4]]

# ===== 浅拷贝: 外层新, 内层共享 =====
shallow = original[:]
print(shallow is original)          # False —— 外层是新的(不同对象)
print(shallow[0] is original[0])    # True!  —— 内层是同一个对象(共享!)
print(id(original[0]), id(shallow[0]))  # 两个 id 相同 —— 铁证内层共享

shallow[0].append(99)               # 改内层
print(original)                     # [[1, 2, 99], [3, 4]] —— 原件被串改!

# ===== 深拷贝: 每一层都是新的 =====
deep = copy.deepcopy(original)
print(deep is original)             # False
print(deep[0] is original[0])       # False —— 内层也是新的(不共享!)
deep[0].append(999)                 # 改内层
print(original)                     # [[1, 2, 99], [3, 4]] —— 原件不受影响 ✓

# ===== 一眼看穿: is / id 是验证"独立还是共享"的探针 =====
def is_shared(a, b):
    return a is b   # True=同一对象(共享), False=不同对象(独立)

print("外层:", is_shared(shallow, original))        # False(浅拷贝外层独立)
print("内层:", is_shared(shallow[0], original[0]))  # True(浅拷贝内层共享 → 危险!)

# 核心: 跑一遍就懂 —— 浅拷贝 shallow[0] is original[0] 为 True(共享, 改内层串原件);
#   深拷贝则全 False(完全独立)。用 is/id 当探针, 一眼看穿"假独立"。

这几段代码,把浅拷贝的"假独立",idis 照得清清楚楚浅拷贝那段:shallow is originalFalse(外层是新的),可 shallow[0] is original[0] 却是 True(内层是同一个对象!),两个 id 一模一样——这就铁证如山地揭示了"外层独立、内层共享";于是改 shallow[0],original 被串改了深拷贝那段:deep[0] is original[0] 也是 False(内层也是新的、不共享),改 deep[0],original 纹丝不动最妙的是那个 is_shared 小工具:它把 is 变成了一个"探针",一调用就能告诉你"这两个东西,是共享的同一个,还是独立的两个"这,正是我想用这几段代码,留给每一个写 Python 的人的最后一课:当你对"这份拷贝到底独不独立"心里没底时,别猜,用 isid() 这两个"探针",把对象的真实身份查出来——copy[0] is original[0] 一打印,是共享还是独立,立刻见分晓"引用共享"这种看不见、摸不着、却又最容易出 bug 的东西,唯有用 is/id() 把它变得"可见",你才能真正地掌控它、而不是被它暗算

写在最后

回头看,这场由"浅拷贝"引发的、改副本却串改原件的事故,真正教给我的,是一个比"用 deepcopy"本身更深的道理:我们日常说的"复制一份",在脑海里是一个"从里到外、彻底独立"的简单、完整的概念;可在计算机的世界里,"复制"却是一个有"深度层次"的、需要精确界定"到底复制到哪一层"的概念;而我们那个"理所当然的、完整的'复制'"的直觉,和计算机里"默认只复制一层(浅)"的现实之间的落差,正是 bug 滋生的温床我犯的错,本质是用"现实世界里复制一份文件(里外都是新的)"的朴素直觉,去套了"计算机里复制一个引用结构(默认只复制外层指针)"的技术现实。这让我深刻地领悟到:编程,常常要求我们把日常那些"模糊、笼统"的概念(复制、相等、删除、修改……),拆解、细化成计算机层面"精确、有层次"的操作;而很多 bug,就源于我们把日常的粗略概念,想当然地等同于了计算机的精确语义所以,对那些"看似简单、人人都懂"的基础操作("复制""比较""赋值"),反而要多一份较真:追问它在计算机里"精确地"意味着什么——复制了几层?比的是值还是引用?改的是副本还是原件?把粗略的日常概念,翻译成精确的技术理解——这,是我用一次"浅拷贝串改"的事故,换来的、关于 Python、也关于编程严谨性的、最朴素也最深刻的领悟。如果这篇复盘,能让你在下一次拷贝嵌套结构前,先想一句"这是浅拷贝还是深拷贝、我要改的内层独立吗",那我对着那个被串改的原件熬的这大半天,就值了。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

我给 AI Agent 接了删数据、发退款这种高危工具还让它全自动跑,结果它判断失误自主执行了一个不可逆操作、造成真实损失,我对着这次没有人能拦一下的事故复盘

2026-6-2 4:52:43

技术教程

我写的 JS 里 setTimeout、Promise 和同步代码混在一起,打印顺序完全不按我写的来,Promise 居然比 setTimeout 先跑,我对着事件循环排查了大半天的复盘

2026-6-2 5:06:44

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索