跳到内容

mutable-argument-default (B006)

源自 flake8-bugbear linter。

有时提供修复。

作用

检查是否使用了可变对象作为函数参数的默认值。

为什么这不好?

函数默认值只在函数定义时计算一次。

然后,同一个可变对象会在所有对该函数的调用中共享。 如果对象被修改,这些修改将在调用之间持续存在,这可能导致意外行为。

相反,最好使用不可变数据结构,或者使用 None 作为默认值,并在函数体中为每次调用初始化一个新的可变对象。

具有不可变类型注解的参数将被此规则忽略。 标准库之外的类型可以使用 lint.flake8-bugbear.extend-immutable-calls 配置选项标记为不可变类型。

已知问题

可变参数默认值可以有意地用于缓存计算结果。 使用 None 或不可变数据结构替换默认值并不适用于此类用法。 相反,最好使用标准库中的 @functools.lru_cache 装饰器。

示例

def add_to_list(item, some_list=[]):
    some_list.append(item)
    return some_list


l1 = add_to_list(0)  # [0]
l2 = add_to_list(1)  # [0, 1]

建议改为

def add_to_list(item, some_list=None):
    if some_list is None:
        some_list = []
    some_list.append(item)
    return some_list


l1 = add_to_list(0)  # [0]
l2 = add_to_list(1)  # [1]

Options (选项)

修复安全性

此修复程序被标记为不安全,因为它将可变默认值替换为 None 并在函数体中初始化它,这可能不是用户想要的,如上所述。

参考