Python 为什么默认参数不应该使用可变对象
发布时间 - 2026-01-29 00:00:00 点击率:次Python函数默认参数在定义时求值,可变对象如[]、{}被重复使用导致状态残留;正确做法是用None作默认值并在函数内初始化。
为什么 def func(x=[]): 会“记住”上次调用的修改
Python 函数的默认参数在函数定义时就完成求值,而不是每次调用时重新创建。这意味着 [] 这个空列表对象只在 def 执行那一刻生成一次,后续所有未传参的调用都共享这个同一对象。
常见错误现象:
def append_to(a, lst=[]):
lst.append(a)
return lst
print(append_to(1)) # [1]
print(append_to(2)) # [1, 2] ← 意外!不是 [2]
- 根本原因不是“变量被污染”,而是
lst始终指向同一个list实例 - 该行为对所有可变对象都成立:包括
{}、set()、自定义类实例等 - 不可变对象(如
None、0、"a")没这个问题,因为它们无法被原地修改
正确写法:用 None 作为占位符
标准解法是把默认值设为 None,再在函数体内显式初始化可变对象。
def append_to(a, lst=None):
if lst is None:
lst = []
lst.append(a)
return lst-
is None比== None更安全,且是 Python 社区惯例 - 如果需要预设初始内容(比如默认带一个元素),直接写
lst = [default_item] - 不要用
if not lst:判断——空列表是 falsy,但用户可能真想传入空列表
哪些场景容易踩坑
这类问题高发于构造器、缓存逻辑、递归辅助参数、配置合并等场景。
-
类方法中默认参数用
dict:导致多个实例共享同一字典,互相覆盖键值 -
装饰器里缓存结果:若用
cache={}当默认参数,所有被装饰函数共用一个缓存字典 -
递归函数的 accumulator:比如
def flatten(lst, acc=[]),不同调用链会混在一起 - Flask/Django 视图函数:默认参数若含可变对象,在多请求下状态错乱,极难复现
检查现有代码是否受影响
搜索项目中所有形如 =[]、={}、=set() 的函数参数定义,尤其是非 None 默认值。
- 静态检查工具(如
pylint)能报dangerous-default-value警告 - 运行时可通过
inspect.signature(func).parameters查看默认值对象 ID 是否变化 - 注意嵌套结
构:例如
def f(d={"k": []})同样危险——外层 dict 不可变,但内部 list 是可变的
真正麻烦的不是语法错误,而是它只在特定调用序列下暴露,且表现像“偶发 bug”。一旦默认参数里藏了可变对象,它的生命周期就脱离了你的直觉控制。
# python
# go
# app
# 工具
# 递归函数
# django
# python函数
# 为什么
# flask
# if
# 递归
# 对象
# default
# bug
# 默认值
# 多个
# 求值
# 设为
# 并在
# 这个问题
# 这类
# 自定义
# 只在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何确保西部建站助手FTP传输的安全性?
如何快速搭建二级域名独立网站?
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Laravel如何实现多对多模型关联?(Eloquent教程)
Android GridView 滑动条设置一直显示状态(推荐)
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
用v-html解决Vue.js渲染中html标签不被解析的问题
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
青岛网站建设如何选择本地服务器?
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
如何在Tomcat中配置并部署网站项目?
如何快速上传建站程序避免常见错误?
Android Socket接口实现即时通讯实例代码
C++用Dijkstra(迪杰斯特拉)算法求最短路径
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
HTML 中如何正确使用模板变量为元素的 name 属性赋值
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
javascript基于原型链的继承及call和apply函数用法分析
如何在Windows服务器上快速搭建网站?
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
Laravel如何使用Blade组件和插槽?(Component代码示例)
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
详解Oracle修改字段类型方法总结
Python数据仓库与ETL构建实战_Airflow调度流程详解
Laravel如何为API编写文档_Laravel API文档生成与维护方法
高防服务器如何保障网站安全无虞?
如何用免费手机建站系统零基础打造专业网站?
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
英语简历制作免费网站推荐,如何将简历翻译成英文?
网页设计与网站制作内容,怎样注册网站?
如何快速搭建高效WAP手机网站?
如何用JavaScript实现文本编辑器_光标和选区怎么处理
Laravel如何记录自定义日志?(Log频道配置)
Python函数文档自动校验_规范解析【教程】
如何在Windows环境下新建FTP站点并设置权限?
Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】
Bootstrap CSS布局之列表
java获取注册ip实例
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
如何彻底删除建站之星生成的Banner?
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
Laravel怎么在Controller之外的地方验证数据
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
如何有效防御Web建站篡改攻击?
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
网站图片在线制作软件,怎么在图片上做链接?


