当前栏目
把陷阱去掉了,反倒踩进了新的陷阱?
相信很多人都知道,Python有一个默认参数陷阱。函数的默认参数不能使用可变类型,否则会导致运行结果跟你想的不一样。例如:
这段代码运行的时候,如果传入了一个列表,那么就往列表里面添加青南和产品经理并用逗号连接起来打印。如果没有传入参数,就打印青南,产品经理。看起来似乎没有问题。但如果你不带参数多运行几次,就会发现问题出来了:
为什么每次不传入参数的时候,打印的结果都不一样?而且越来越长?这个原因我公众号以前已经讲过了,根本原因就在于默认参数user_list=[]这里的默认值[]是在代码运行时(Runtime)启动的时候就初始化的,每次调用函数一直使用这同一个对象,并不是每次调用函数的时候初始化。
要解决这个问题也非常简单,默认参数使用不可变对象就可以了:
最近,我在上古代码中开发新功能,看到有一段处理Exception的函数,默认参数就使用的字典。代码大概长成下面这样:
于是我就顺手把它改了:
理论上讲,我这样改移除了一个隐患,并且对后面的具体代码来说,param_dict始终都是一个字典,应该没有什么问题才对。
结果不久以后,有人给我报Bug。我一看,不就是我改的这个函数报错了吗。一通分析函数调用栈,发现了问题的原因。
这个函数原来是这样写的:
而上古代码里面,调用这个函数的时候,有下面两种写法:
当他用不到param_dict参数的时候,他竟然主动传了个None进去。这样一来,他传入的None就会被我强制转换为空字典。于是代码就会走到extra_msg.format(**param_dict)里面。这个时候由于没有填充大括号中的参数,于是就报错了:
这个新的bug解决起来也简单,再判断一下param_dict是不是空就可以了:
这真的应验了那句话,当一段显然有问题的代码竟然正常运行的时候,你就不要去动他了,它可能处于负负得正的状态,这一改反而可能把它改错了。
相关文章
- JS 当中的函数柯里化和高阶函数
- 数据提取-JsonPath
- Selenium与PhantomJS
- 数据提取-PyQuery
- package.json中script的生命周期
- JavaScript反爬之哈希算法
- 性能调优命令之jstat
- 性能调优命令之jstack
- 基于docker Jenkins搭建持续集成自动化测试环境,管理、配置、运行 Node 节点与 Slave 分布式运行
- selenium Webdriver自动化测试之执行JavaScript脚本
- Python3.x:Selenium+PhantomJS爬取带Ajax、Js的网页及获取JS返回值
- HTML基础之JS
- Python装饰器、生成器、内置函数、json
- 实现我博客旁边的线条效果 html canvas-nest.js 源码
- 陪你去看 Lodash.js 起步
- 数字格式化的 js 库
- 内网 Ubuntu 20.04 搭建 docusaurus 项目(或前端项目)的环境(mobaxterm、tigervnc、nfs、node)
- react实战系列 —— 起步(mockjs、第一个模块、docusaurus)
- 前端学习 node 快速入门 系列 —— 报名系统 - [express]
- 前端学习 node 快速入门 系列 —— 服务端渲染