WMX · 随记
·Python· 3 分钟阅读

默认参数里的列表,为什么会记住上一次调用

把空列表写在函数签名里,看起来每次调用都会得到一个新列表。实际上连续两次追加后,第二次结果往往包含第一次的数据,测试之间也可能互相污染。

▶ 本文含视频讲解
▶ 教学视频手动播放 · 英语讲解

Python Tutorial for Beginners

Python 入门课程作为语法与编程背景复习;本文使用的较新标准库特性不保证在该课程中逐项覆盖。此为外部原版课程,多篇笔记可能共用;未剪辑为本文专属视频。

播放器需要能访问 YouTube 的网络;若这里无法加载,可打开原视频。本文与本地图解仍可独立阅读。

Python 系列概览:输入校验、数据处理与行为验证
Python 系列概览:输入校验、数据处理与行为验证 点击图片查看大图 ↗

问题从哪里出现

把空列表写在函数签名里,看起来每次调用都会得到一个新列表。实际上连续两次追加后,第二次结果往往包含第一次的数据,测试之间也可能互相污染。

理解核心机制

默认表达式在函数定义执行时求值,而不是在每次调用时求值。对于需要独立容器的参数,可用 None 作为缺省标记,在函数内部创建列表。若 None 本身有业务含义,则使用独立的哨兵对象。

动手做一个小实验

Python 3.11 或更新版本,仅使用标准库;将示例保存为 demo.py 后执行 python3 demo.py。

Python10 行 · 可横向滚动
def append_item(value, items=None):
    if items is None:
        items = []
    items.append(value)
    return items

first = append_item("java")
second = append_item("python")
assert first == ["java"] and second == ["python"]
print(first, second)

适用边界与常见误区

传入显式列表后,函数仍会修改它;修复默认参数并不等于保证无副作用。接口必须说明是否修改调用方的对象,不能只依赖类型提示表达这一点。

继续练习

分别省略参数、传入空列表、连续复用同一列表,观察对象标识和内容。再设计一个返回新列表且不修改输入的版本。

参考资料

阅读相关官方文档或原始资料 ↗

← 返回文章归档