默认参数的一些bug

  1. 类初始化函数中的默认参数bug

默认参数如果是不可变类型, 比如基础数据类型 int str 和不可变 tuple等, 这些是不会出bug的, 而用到可变默认参数, 就会出现幽灵般的bug, 看下面代码

class HauntedBus:
    def __init__(self, passengers = []):
        self.passengers = passengers
    def pick(self, name):
        self.passengers.append(name)
    def drop(self, name):
        self.passengers.remove(name)
    def __repr__(self):
        return str(self.passengers)

if __name__ == '__main__':
    bus1 = HauntedBus(['Alice', 'Bill'])
    print('bus1 is {}'.format(bus1))
    bus1.pick('Charlie')
    bus1.drop('Alice')
    print('bus1 is {}'.format(bus1))
    bus2 = HauntedBus()
    bus2.pick('Charlie')
    print('bus2 is {}'.format(bus2))
    bus3 = HauntedBus()
    print('bus3 is {}'.format(bus3))
    print(dir(HauntedBus.__init__))
    print(HauntedBus.__init__.__defaults__)
    bus2.pick('lucy')
    print(HauntedBus.__init__.__defaults__)

运行结果:

bus1 is ['Alice', 'Bill']
bus1 is ['Bill', 'Charlie']
bus2 is ['Charlie']
bus3 is ['Charlie']
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
(['Charlie'],)
(['Charlie', 'lucy'],)

Process finished with exit code 0

在载入模块 HauntedBus 的时候, 就已经创建了默认参数passengers, 保存在 HauntedBus._init _._defaults _ 中, 由于是类属性而不是 实例属性, 所以只会保存一份, 并且以引用方式赋值, 所以会有 N个实例共用一个 列表的情况, 导致数据混乱.
函数是一等对象, 同理会有一样的问题, 一般默认参数都使用 none 之类的不可变参数, 并用if来判断是否传参后 再进行创建 列表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值