关于Python中类(class)的初始化

本文探讨了Python中类的两种初始化方式及其对实例变量的影响。通过对比classA和classB的实例化过程,揭示了列表作为类变量时,不同初始化方式导致的共享与独立问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、两种初始化方式

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地址是不同的,二者不会相互影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌哒哒虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值