鱼C论坛

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

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

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

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

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

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

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

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

判断(4分)
对于下面函数,多次调用时,输出的结果不同
def f(a=[1]):
    a.append(1)
    print(a)

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

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

    
>>> f()
[1, 1]
>>> f()
[1, 1, 1]
>>> f()
[1, 1, 1, 1]

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

函数定义时生成一个对象作为默认参数,每次调用函数(不传参),变量a指向该对象
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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


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

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

    
>>> f1()
{0.31997754747288976, 1}
>>> f1()
{0.31997754747288976, 1, 0.8058917007332184}
>>> 

如果把代码修改成
def f2():
    a=[1]
    a.append(1)
    print(a)
输出的结果也是不变的
这似乎说明a = [1]这条语句在f()中只被执行了一次

“如果有参数值可用,默认参数就没有作用。”
函数怎么判断有没有可用参数值呢
在第一次调用f()并结束的时候,
a没有作为局部变量消失么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

函数定义时生成一个对象作为默认参数,每次调用函数(不传参),变量a指向该对象
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

使用道具 举报

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

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

需要可变参数类型的默认参数的话,一般可以如下处理
def f3(a=None):
    if a is None:
        a = [1]
    a.append(1)
    return a
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

使用道具 举报

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

确实...
习惯晚睡了,多谢解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-26 18:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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