Discuss / Python / 默认参数动态调用原因

默认参数动态调用原因

Topic source

对该方面的浅薄猜测,如果存在有错误,希望能在评论区给予指正

作者提到:

很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了'END'后的list。

原因解释如下:

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

换个说法就是:Python在第一次调用该函数的时候,会单独为默认参数设置一个地址,并且该地址在函数运行完后不会消失。当再次调用这个函数时,便会提取默认参数地址的值,从而导致了这个结果。

而对于作者的解:

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

其主要原理是在函数内部新建立了一个变量,而该变量在函数调用完毕之后便会消失,因此这个解相当于在每次调用函数时重新创建L,以解决上述的问题。根据这个想法,这个问题也可以这样解决

def add_end(L=[]):
    if L == []:
        s = []
        s.append('END')
        return s
    L.append('END')
    return L

最后,为什么正常调用没关系?

>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'END']

因为传递的是地址,因此不需要从默认参数地址中提取。

大家可以用id()函数求变量地址来试一试。

命名关键词详细信息:https://www.zhihu.com/question/57726430

廖雪峰

#3 Created at ... [Delete] [Delete and Lock User]

默认参数一定要用不可变对象,这是为了避坑

不可变对象包括 None, str, True, False, 数字等


  • 1

Reply