Python函数默认参数的问题

TL;DR Python的默认参数实现机制很容易导致难以调试的bug。正确的使用方法是避免使用可变类型作为默认参数。

默认可变参数带来的问题

函数的默认参数如果是可变类型的变量,可能会带来难以debug的bug。def定义的函数,在解释器定义为函数时,会计算默认参数的值,并将值存储在 func_defaults 属性中,并且该默认值只会初始化一次

def append_to_list(item, list_=[]):
    list_.append(item)
    print(list_)

print(".func_defaults:", append_to_list.func_defaults)
append_to_list(0)
print(".func_defaults:", append_to_list.func_defaults)
append_to_list(1)
print(".func_defaults:", append_to_list.func_defaults)
`</pre>

运行以上代码,则会有如下输出:

<pre>`('.func_defaults:', ([],))
[0]
('.func_defaults:', ([0],))
[0, 1]
('.func_defaults:', ([0, 1],))
`</pre>

#### 解决方案

<pre>`def append_to_list(item, list_=None):
    if list_ is None:
        list_ = []
    list_.append(item)
    print(list_)

print(".func_defaults:", append_to_list.func_defaults)
append_to_list(0)
print(".func_defaults:", append_to_list.func_defaults)
append_to_list(1)
print(".func_defaults:", append_to_list.func_defaults)
`</pre>

运行以上代码,则会有如下输出:

<pre>`('.func_defaults:', (None,))
[0]
('.func_defaults:', (None,))
[1]
('.func_defaults:', (None,))

参考

  1. 编写高质量Python代码的91个建议 第32个建议