问题描述
实习的时候,开发阶段,需要一个奇怪的 bug
class PowItem():
def __init__(self, base, degree, coefficient=IntItem('1'), item_str=""):
...
...
class IntItem():
def __int__(self, item_str):
self.item_str = item_str
主要是如上代码,我在初始化PowItem类的时候发现,我没传coefficient参数,默认值应该是
IntItem("1") 但是实际却变成了 IntItem("-1"),多了一个负号,百思不得其解
PowItem(base=IntItem('2'), degree=IntItem('2'))
分析
问题就出在了 python 可变与不可变默认参数表现出的不同形式
默认参数的值只在定义时计算一次,因此每次使用默认参数调用函数时,得到的默认参数值是相同的,也就是其数据地址都指向了同一块,我在初始化 PowItem 类的之前,已经使用了 PowItem,并改变其coefficient 为 IntItem("-1"),这就相当于把 coefficient 的默认改成了 IntItem("-1"),因为数据的内存地址相同(可以通过 id() 查看)。
解决
参考下面博客里的解决方法:
不可变的默认参数的多次调用不会造成任何影响,可变默认参数的多次调用的结果不符合预期。那么在使用可变默认参数时,就不能只在函数定义时初始化一次,而应该在每次调用时初始化。
最佳解决方法就是定义函数时指定可变默认参数的值为None,在函数体内部重新绑定默认参数的值:
class PowItem():
def __init__(self, base, degree, coefficient=None, item_str=""):
self.coefficient = IntItem('1') if coefficient is None else coefficient
...
...
class IntItem():
def __int__(self, item_str):
self.item_str = item_str