负离负离子 发表于 2020-4-22 00:01:32

函数中默认参数是怎么工作的?

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

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

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

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

def f(a=):
    a.append(1)
    print(a)

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

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

   
>>> f()

>>> f()

>>> f()


为什么会这样呢?
我以为应该每次调用都输出才对啊

倒戈卸甲 发表于 2020-4-22 00:17:18

你的以为没有问题,你可以把列表换成数字,里面的方法变成普通的加法比如加等于一,再看看。

倒戈卸甲 发表于 2020-4-22 00:24:03

不过默认参数的权限级别确实不是很高就是了,仅当需要一个参数值却没能传入一个参数值的情况,默认参数会生效,如果有参数值可用,默认参数就没有作用。

负离负离子 发表于 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=
    a.append(1)
    print(a)
输出的结果也是不变的
这似乎说明a = 这条语句在f()中只被执行了一次

“如果有参数值可用,默认参数就没有作用。”
函数怎么判断有没有可用参数值呢
在第一次调用f()并结束的时候,
a没有作为局部变量消失么

fish_游鱼 发表于 2020-4-22 01:30:40

本帖最后由 fish_游鱼 于 2020-4-22 01:36 编辑

函数定义时生成一个对象作为默认参数,每次调用函数(不传参),变量a指向该对象

负离负离子 发表于 2020-4-22 01:51:15

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

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

这样的话感觉把可变参数类型作为默认参数的值,好像是一件非常危险的行为啊
因为一旦函数中有修改这个值的行为
那我调用这个函数会产生什么样的结果就要追本溯源才能知道了

fish_游鱼 发表于 2020-4-22 02:03:44

负离负离子 发表于 2020-4-22 01:51
如果是这样的机制话,那确实是这个结果,大概了解了,多谢

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

需要可变参数类型的默认参数的话,一般可以如下处理
def f3(a=None):
    if a is None:
      a =
    a.append(1)
    return a

倒戈卸甲 发表于 2020-4-22 07:24:45

负离负离子 发表于 2020-4-22 01:51
如果是这样的机制话,那确实是这个结果,大概了解了,多谢

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

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

负离负离子 发表于 2020-4-22 09:31:32

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

确实...
习惯晚睡了,多谢解答{:9_222:}
页: [1]
查看完整版本: 函数中默认参数是怎么工作的?