可变的函数参数默认值有什么好的用法?
在Python中,一个常见的错误是把可变对象作为函数参数的默认值。下面是一个例子,摘自David Goodger的这篇优秀文章:
>>> def bad_append(new_item, a_list=[]):
a_list.append(new_item)
return a_list
>>> print bad_append('one')
['one']
>>> print bad_append('two')
['one', 'two']
关于为什么会出现这个问题的解释可以在这里找到。
现在我想问的是:这种语法有什么好的用处吗?
我的意思是,如果每个人遇到这个问题都犯同样的错误,调试后理解了问题,然后从此开始避免它,那这种语法还有什么意义呢?
9 个回答
19
也许你并没有改变那个可以变动的参数,但你确实希望它是可以变动的:
def foo(x, y, config={}):
my_config = {'debug': True, 'verbose': False}
my_config.update(config)
return bar(x, my_config) + baz(y, my_config)
(是的,我知道在这种情况下你可以使用 config=()
,但我觉得这样不太清楚,也不够通用。)
96
你可以用它在函数调用之间保存一些值:
def get_from_cache(name, cache={}):
if name in cache: return cache[name]
cache[name] = result = expensive_calculation()
return result
不过通常这种情况用类来做会更好,因为这样你可以有更多的属性来清理缓存等等。
24
这个页面是权威答案:http://effbot.org/zone/default-values.htm
它还提到了三种“好”的情况,适合使用可变的默认参数:
- 在回调函数中,将局部变量绑定到外部变量的当前值
- 缓存/记忆化
- 局部重新绑定全局名称(用于高度优化的代码)