可变的函数参数默认值有什么好的用法?

142 投票
9 回答
25690 浏览
提问于 2025-04-17 12:24

在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

它还提到了三种“好”的情况,适合使用可变的默认参数:

  • 在回调函数中,将局部变量绑定到外部变量的当前值
  • 缓存/记忆化
  • 局部重新绑定全局名称(用于高度优化的代码)

撰写回答