最近在做项目的时候遇到一个很奇怪的关于对象中空list赋值的bug,大概情况如下。
项目场景:
环境:Anaconda Python3.10
编辑器:PyCharm 2021.2.3
问题描述:
我首先定义了一个类ListObject,里面有一个list类型的属性array,它有时候没有初始值,有时候有初始值,于是我定义了一个简单的构造函数,其中array的默认值是空list:
class ListObject:
def __init__(self, name, array=[]):
self.name = name
self.array = array
def add(self, data):
self.array.append(data)
然后我创建了这个类的两个对象,并对每个对象的array分别简单赋值,如下:
list1 = ListObject("list1")
list1.array.append(1)
print(list1.name,list1.array)
list2 = ListObject("list2")
list2.array.append(2)
print(list1.name,list1.array)
print(list2.name,list2.array)
在我设想中的输出应该是这样:
list1 [1]
list1 [1]
list2 [2]
但是实际上,它的输出结果是这样:
list1 [1]
list1 [1, 2]
list2 [1, 2]
原因分析:
从name属性输出的结果来看,list1和list2,确实是两个不同的对象,但是它们的array却指向了同一个list。
背后的具体机制我不太理解,如果有知道问题原因或机制的,欢迎留言探讨!
解决方案:
发现bug了,肯定要找到解决方案了。我的解决方案也很简单,就是将构造函数的参数默认值从空list,改成None,然后根据参数是否有初始值的情况来给array赋值。如下:
class ListObject:
def __init__(self, name, array=None):
self.name = name
if array is None:
self.array = []
else:
self.array = array
def add(self, data):
self.array.append(data)
再运行一次前面的赋值和输出:
list1 [1]
list1 [1]
list2 [2]
就得到想要的正确结果了。这就是这次的踩坑实录了。