一、两种初始化方式
class A:
num1 = 10
list1 = []
def read(self):
print('num1=', self.num1)
print('list1=', self.list1)
class B:
def __init__(self):
self.num1 = 10
self.list1 = []
def read(self):
print('num1=', self.num1)
print('list1=', self.list1)
本文主要讨论两种初始化方式的不同之处,事实上在编写代码的过程中正是第一种初始化方式导致了我的程序出现问题。
二、class A出现的问题
现有如下主函数:
if __name__ == '__main__':
a1 = A()
a2 = A()
a1.num1 = 5
a1.list1.append('a1')
a2.num1 = 6
a2.list1.append('a2')
print("a1:")
a1.read()
print("a2:")
a2.read()
我们期望的输出结果是:
a1:num1=5,list1=[‘a1’]
a2:num1=6,list1=[‘a2’]
但实际输出结果如下:
a1:
num1= 5
list1= ['a1', 'a2']
a2:
num1= 6
list1= ['a1', 'a2']
如果采用class B的初始化方式,运行类似的主函数,如下:
b1 = B()
b2 = B()
b1.num1 = 5
b1.list1.append('b1')
b2.num1 = 6
b2.list1.append('b2')
print('b1:')
b1.read()
print('b2:')
b2.read()
此时,我们得到了期望的结果:
b1:
num1= 5
list1= ['b1']
b2:
num1= 6
list1= ['b2']
在写代码的过程中,我正是不小心采用了class A的方式初始化“列表”这类复杂的数据结构。通常“列表”这类变量存储的是指向数据单元的地址。通过分析可知,对于所有class A的实例,它们的list1具有相同的初值,也就是相同的地址指针,因此它们的list1是共用的。
可以证实上述想法:
print('a1.list1_id=', id(a1.list1))
print('a2.list1_id=', id(a2.list1))
print('b1.list1_id=', id(b1.list1))
print('b2.list1_id=', id(b2.list1))
运行结果如下:
a1.list1_id= 9848272
a2.list1_id= 9848272
b1.list1_id= 9849432
b2.list1_id= 47561264
可见a1、a2中的list1具有相同的地址,二者会发生相互影响;而b1、b2中的list1地址是不同的,二者不会相互影响。