鱼C论坛

 找回密码
 立即注册
查看: 1031|回复: 8

[已解决]函数中默认参数是怎么工作的?

[复制链接]
发表于 2020-4-22 00:01:32 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 负离负离子 于 2020-4-22 00:05 编辑

我以为就是执行函数的时候,没有对应的参数就使用默认参数

可是在做题的时候发现好像和我想得不太一样

判断(4分)
对于下面函数,多次调用时,输出的结果不同

  1. def f(a=[1]):
  2.     a.append(1)
  3.     print(a)
复制代码


正确答案:A(√)你错选为B(×)

实际调用:
  1. >>> def f(a=[1]):
  2.     a.append(1)
  3.     print(a)

  4.    
  5. >>> f()
  6. [1, 1]
  7. >>> f()
  8. [1, 1, 1]
  9. >>> f()
  10. [1, 1, 1, 1]
复制代码


为什么会这样呢?
我以为应该每次调用都输出[1, 1]才对啊
最佳答案
2020-4-22 01:30:40
本帖最后由 fish_游鱼 于 2020-4-22 01:36 编辑

函数定义时生成一个对象作为默认参数,每次调用函数(不传参),变量a指向该对象
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-4-22 00:17:18 From FishC Mobile | 显示全部楼层
你的以为没有问题,你可以把列表换成数字,里面的方法变成普通的加法比如加等于一,再看看。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-22 00:24:03 From FishC Mobile | 显示全部楼层
不过默认参数的权限级别确实不是很高就是了,仅当需要一个参数值却没能传入一个参数值的情况,默认参数会生效,如果有参数值可用,默认参数就没有作用。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-22 00:54:59 | 显示全部楼层
本帖最后由 负离负离子 于 2020-4-22 01:45 编辑
倒戈卸甲 发表于 2020-4-22 00:17
你的以为没有问题,你可以把列表换成数字,里面的方法变成普通的加法比如加等于一,再看看。


如果是数字的话,确实和想象得结果是统一的

可是列表为什么会出现这样的情况呢
事实上似乎可变数据类型都会这样
  1. >>> def f1(a={1}):
  2.     a.add(random.random())
  3.     print(a)

  4.    
  5. >>> f1()
  6. {0.31997754747288976, 1}
  7. >>> f1()
  8. {0.31997754747288976, 1, 0.8058917007332184}
  9. >>>
复制代码


如果把代码修改成
  1. def f2():
  2.     a=[1]
  3.     a.append(1)
  4.     print(a)
复制代码

输出的结果也是不变的
这似乎说明a = [1]这条语句在f()中只被执行了一次

“如果有参数值可用,默认参数就没有作用。”
函数怎么判断有没有可用参数值呢
在第一次调用f()并结束的时候,
a没有作为局部变量消失么
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-22 01:30:40 | 显示全部楼层    本楼为最佳答案   
本帖最后由 fish_游鱼 于 2020-4-22 01:36 编辑

函数定义时生成一个对象作为默认参数,每次调用函数(不传参),变量a指向该对象
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-22 01:51:15 | 显示全部楼层
fish_游鱼 发表于 2020-4-22 01:30
函数定义时生成一个对象作为默认参数,每次调用函数(不传参),变量a指向该对象

如果是这样的机制话,那确实是这个结果,大概了解了,多谢

这样的话感觉把可变参数类型作为默认参数的值,好像是一件非常危险的行为啊
因为一旦函数中有修改这个值的行为
那我调用这个函数会产生什么样的结果就要追本溯源才能知道了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-22 02:03:44 | 显示全部楼层
负离负离子 发表于 2020-4-22 01:51
如果是这样的机制话,那确实是这个结果,大概了解了,多谢

这样的话感觉把可变参数类型作为默认参数的 ...

需要可变参数类型的默认参数的话,一般可以如下处理
  1. def f3(a=None):
  2.     if a is None:
  3.         a = [1]
  4.     a.append(1)
  5.     return a
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-22 07:24:45 From FishC Mobile | 显示全部楼层
负离负离子 发表于 2020-4-22 01:51
如果是这样的机制话,那确实是这个结果,大概了解了,多谢

这样的话感觉把可变参数类型作为默认参数的 ...

你这么晚才睡啊。昨天突然困了,然后就睡着了。楼上提出了解决方案,每次调用函数都初始化列表a。但其实你的担心是多余的,因为你实际写程序又不是做题,一定有办法限制其负面影响。就拿这个例子为例,代码中通过a.len()就能拿到其运行次数或者说列表长度,结合if判断就能让程序在某个业务要求的范围内运行。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-22 09:31:32 | 显示全部楼层
倒戈卸甲 发表于 2020-4-22 07:24
你这么晚才睡啊。昨天突然困了,然后就睡着了。楼上提出了解决方案,每次调用函数都初始化列表a。但其实 ...

确实...
习惯晚睡了,多谢解答
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-17 17:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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