鱼C论坛

 找回密码
 立即注册
查看: 3065|回复: 6

[技术交流] 默认参数最好不为可变对象

[复制链接]
发表于 2021-1-5 21:36:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 一个账号 于 2021-1-5 22:25 编辑

在之前写的一个项目中,就遇到这个错误。

在传递默认参数时,新手很容易遇到这个错误。

这个错误是什么呢?我们来看一个例子:

  1. >>> def func(va, li=[]):
  2.         li.append(va)
  3.         print(li)

  4.        
  5. >>> func("A")
  6. ['A']
  7. >>> func("B", ["C", "D"])
  8. ['C', 'D', 'B']
  9. >>> func("E")
  10. --------- 隐藏 ---------
  11. >>>
复制代码


你们猜猜最后输出的是什么呢?

  1. >>> def func(va, li=[]):
  2.         li.append(va)
  3.         print(li)

  4.        
  5. >>> func("A")
  6. ['A']
  7. >>> func("B", ["C", "D"])
  8. ['C', 'D', 'B']
  9. >>> func("E")
  10. ['A', 'E']
  11. >>>
复制代码


Python 中的 def 语句在每次执行的时候都初始化一个函数对象,这个函数对象就是我们要调用的函数,

可以把它当成一个一般的对象,只不过这个对象拥有一个可执行的方法和部分属性。

对于参数中提供了初始值的参数,由于 Python 中的函数参数传递的是对象,

也可以认为是传地址,在第一次初始化 def 的时候,会先生成这个可变对象的内存地址,

然后将这个默认参数 li 会与这个内存地址绑定。在后面的函数调用中,如果调用方指定了新的默认值,

就会将原来的默认值覆盖。如果调用方没有指定新的默认值,那就会使用原来的默认值。

============================================分割线============================================

在这个帖子中顺便也写一下最近发现的一个有趣的事情

来看一个简单的例子:

  1. li = [1, 2, 3, 4, 5]
  2. print(li[5])
复制代码


执行一下,和我们的预期一样,会抛出索引错误:

  1. IndexError: list index out of range
复制代码


但是大家来看看这个例子:

  1. li= [1, 2, 3]
  2. print(li[5:])
复制代码


最后会输出一个空列表

  1. []
复制代码

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-1-7 14:00:09 | 显示全部楼层
真不错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-14 15:50:04 | 显示全部楼层
可以可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-14 16:26:33 | 显示全部楼层
那么,避免这个问题的方法是什么呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-14 16:31:56 | 显示全部楼层
真可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-14 17:21:43 | 显示全部楼层
crisfo 发表于 2021-3-14 16:26
那么,避免这个问题的方法是什么呢?

这个完全 是因为你列表中没有这么长的字符,不需要避免,按照自己列表的长度,来截取字符串就可以了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-15 07:43:34 | 显示全部楼层
程序员不秃 发表于 2021-3-14 17:21
这个完全 是因为你列表中没有这么长的字符,不需要避免,按照自己列表的长度,来截取字符串就可以了

不好意思,没表述清楚,我说的是 li = [] 的问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 02:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表