我们先定义一个简单的类,然后实例化两个对象。
class A:
def __init__(self, data=[]):
self.data = data
a1 = A()
a2 = A()
类A的初始化函数有个默认参数值[ ], 这会导致严重的BUG。看下面演示:
print(a1.data) # []
print(a2.data) # []
a1.data.append(1) # 对象a1操作自己的数据
print(a1.data) # [1]
print(a2.data) # [1] a1的操作竟然直接影响到a2的数据
可以看出,对象a1的操作会直接影响到a2的数据。这种现象,极其容易引起难以排除的安全隐患。为什么会有这个现象呢?
这与python对默认值的处理机制有关。默认值在函数定义的时候计算,并作为函数对象的属性,并不是类对象的属性。因此,类实例在初始化时,默认值[]指向的是同一个函数对象的属性,即同一个可变对象[]. 所以,a1与a2对象的data属性,实际上指向的是相同的列表。
可以用下面的语句打印出来函数属性,来验证上面的论断。
print(A.__init__.__defaults__)
# ([],)
所以,实际中,通常使用None作为接收可变值参数的默认值。
网友评论