【发布时间】:2020-10-21 00:00:10
【问题描述】:
在阅读this thread 之后,我还尝试使用默认参数弄脏我的手。因此,以下是具有可变默认参数的相同函数:-
def foo(x = []):
x.append(1)
return x
作为defined in the docs,默认值仅在定义函数时计算一次。
所以,在执行这条语句时,print(foo(), foo(), foo()),我希望输出是这样的:[1] [1, 1] [1, 1, 1]
相反,这是我实际得到的输出:-
>>> print(foo(), foo(), foo())
[1, 1, 1] [1, 1, 1] [1, 1, 1]
语句的执行方式(根据我)是第一个函数调用返回[1],第二个返回[1, 1],第三个函数调用返回[1, 1 , 1] 但它只是重复打印的第三个函数调用返回值。
此外,将相同的函数返回值打印为单独的语句(如该线程中所述)会产生预期的结果,即,
>>> print(foo())
[1]
>>> print(foo())
[1, 1]
>>> print(foo())
[1, 1, 1]
那么,为什么一起打印相同的函数返回值不会像单独执行时那样返回输出呢?
【问题讨论】:
-
您的
print(foo(), foo(), foo())会依次评估每个foo(),但只有在对foo()的所有调用都完成后才会调用print()。同样来自foo()的每个返回都返回对 same 列表的引用。所以print()只打印了三遍。 -
函数实际上返回对对象的引用。在第一个变体中,打印发生在所有 foo 调用之后,并且 print 在第三个“foo”之后的状态中接收到对同一列表的三个引用。
-
我不想让您回到启发您的实验的链接,但它在您的测试中以这种方式表现的原因与它在单独调用中表现的原因相同,并且是在这里给出的 effbot 链接中进行了解释:因为绑定到参数的默认值每次都是 相同的实际对象。您会从不同的语句中看到不同的结果,因为 那个对象 每次都有不同的内容;在单个语句中调用时,您会多次看到相同的结果,因为您正在多次查看同一个对象在所有工作之后。
-
强制链接到Ned Batchelder
-
如果你一次做一个
print(foo()),它会输出你所期望的。我确实假设在组合打印语句中,首先执行所有调用,然后列表具有值 [1,1,1] 然后打印。
标签: python return-value default-parameters