函数中的默认值

2024-04-25 04:40:45 发布

您现在位置:Python中文网/ 问答频道 /正文

Python文档中函数参数中的默认值部分出现以下警告

重要警告:默认值仅计算一次。当默认值是可变对象(如列表、字典或大多数类的实例)时,这会有所不同。例如,以下函数累积在后续调用中传递给它的参数:

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

这会打印出来

[1]

[1,2]

[1,2,3]

如果不希望在后续调用之间共享默认值,则可以这样编写函数:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

我不太明白代码的L=None部分是如何解决这个问题的。你能帮我理解吗。谢谢


Tags: 对象实例函数文档none警告列表参数
3条回答

让我们先讨论解决方案,然后再研究一下问题

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

当您在不传递L的情况下调用时,每次调用函数时都会创建一个新的list。为a传递的值被追加到L并返回新创建的L

这很简单。让我们看看当L的默认值为[]时会发生什么

在Python中,函数参数的默认值在计算def时计算

您可以使用<function_name>.__defaults__看到

mahorir@mahorir-Vostro-3446:~$ python3
Python 3.6.9 (default, Apr 18 2020, 01:56:04)

>>> def fun(a,l=[]):
...     l.append(a);return l
... 
>>> fun.__defaults__
([],)

您可以在开头看到默认值(调用函数之前为空列表) 几次电话后-

>>> fun(1)
[1]
>>> fun(2)
[1, 2]
>>> fun(3)
[1, 2, 3]
>>> fun.__defaults__
([1, 2, 3],)

这当然让每个Python开发人员都感到惊讶

与文档中提到的一样,当您将L=[]放在参数中时,参数的值只计算一次,因此L的列表只创建一次并在调用之间共享

因此,如果您想在每次调用函数时创建一个新列表,那么您必须在函数内部使用类似L = []的语句创建列表。但是如果调用方传递了一个列表,您不想创建一个新的空列表,您只想使用调用方提供给您的列表。这就是这里的None出现的地方,它只是一个信号,表示您需要一个空列表。这就是为什么要使用if来检查参数是否为None,并仅在该参数为None时创建一个空列表

因为None只是一个不可变的值,所以它不会在调用之间共享

None是不可变的,这意味着它不能更改。因此,如果将None设置为参数的默认值,则每次调用函数时它都是相同的,并且将一个新的空列表设置为L(因为它是每次计算的,而不仅仅是第一次调用函数时)

进一步阅读:http://effbot.org/zone/default-values.htm

相关问题 更多 >