flake8:B006: 不要使用空的 list/dict 作为默认值

PEP8: B006 Do not use mutable data structures for argument defaults.

该场景下会导致函数的结果与预期不符

错误示范:

def append(element, seq=[]):
    seq.append(element)
    return seq
    
>>> append(1)  # seq 的默认值是 []
[1]  # 返回值正常
>>> append(2)  # => seq 的默认值变成了 [1]
[1, 2]  # 返回值异常

正确使用示例:

def append(element, seq=None):
    if seq is None:  # 👍
        seq = []
    seq.append(element)
    return seq
    
>>> append(1)  # `seq` is assigned to []
[1]
>>> append(2)  # `seq` is assigned to [] again!
[2]  # 正确的返回预期的数值

这种现象的原因在 Python 常见疑难问题 中有描述

Python’s default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.

参数默认值不过是一个指向那个在compile阶段就已经存在的对象的指针, 如果调用函数时,没有显示指定传入参数值得话。那么所有这种情况下的该参数都会作为编译时创建的那个对象的一种别名存在。如果参数的默认值是一个不可变(Imuttable)数值,那么在函数体内如果修改了该参数,那么参数就会重新指向另一个新的不可变值。而如果参数默认值是和本文最开始的举例一样,是一个可变对象(Muttable),那么情况就比较糟糕了。所有函数体内对于该参数的修改,实际上都是对compile阶段就已经确定的那个对象的修改。

Python官方文档中也有特别提示

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes.

参考文档:

https://florimond.dev/en/posts/2018/08/python-mutable-defaults-are-the-source-of-all-evil/

https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions

https://docs.python-guide.org/writing/gotchas/

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值