Python面向对象面试题解析

本文详细解析了Python中变量如何保存内存地址,不同数据类型如列表、元组和字典的修改行为,浅拷贝和深拷贝的区别,以及引用传递和值传递的概念。重点强调了可变与不可变数据类型在内存操作中的差异。

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

1 一切变量都是对象

1.1 变量的赋值

Python变量保存的是值的引用 也可以说:变量是对内存及其地址的抽象
当你创建一个变量并将一个值赋给它时,Python解释器会在内存中分配一块空间来存储该值,并将变量与该内存地址关联起来。
这样,通过变量就可以访问和操作存储在该内存地址中的值。

当你初始化一个变量时,Python会为该变量分配内存空间,并将该空间的地址赋值给变量。这意味着变量实际上保存的是对内存中对象的引用,而不是对象本身。
当你重新赋值给变量时,Python会为新的值分配新的内存空间,并将新值的地址赋值给变量。这样,变量就引用了新的内存地址和值。

a = 10
b = a

print(id(a))  # 输出: 140737013020368
print(id(b))  # 输出: 140737013020368

a = 20

print(id(a))  # 输出: 140737013020400
print(id(b))  # 输出: 140737013020368
因此,可以看出每次变量的初始化都会开辟新的空间,并将新内容的地址赋值给变量。
这是因为Python采用了对象语义或指针语义,变量保存的是对内存中对象的引用。

1.2 复杂的数据类型,列表,元组,字典等修改与赋值

在Python中,对于可变的复杂数据类型(如列表、字典和集合),当你修改其中的某一项元素的值或者添加、删除元素时,这些操作会改变对象内部元素的地址引用,但不会改变对象本身的地址。

让我们通过一个示例来说明这一点:

a = [1, 2, 3]
print(id(a))  # 输出: 140737013038352

a.append(4)
print(id(a))  # 输出: 140737013038352

a[0] = 10
print(id(a))  # 输出: 140737013038352

a = [5, 6, 7]
print(id(a))  # 输出: 140737013038416

在这个例子中,我们首先创建了一个列表 [1, 2, 3] 并将其赋给变量 a。通过 id() 函数可以查看变量 a 引用的列表对象的内存地址。

接着,我们使用 append() 方法向列表中添加一个元素 4,然后将列表的第一个元素修改为 10。在这些操作之后,通过 id(a) 再次查看变量 a 引用的列表对象的内存地址,发现它仍然是相同的。

然而,当我们执行 a = [5, 6, 7] 这个重新赋值操作时,变量 a 将引用一个新的列表对象。此时,通过 id(a) 查看变量 a 引用的列表对象的内存地址,发现它已经改变了。

这表明对列表进行修改或添加元素,并不会改变列表对象本身的地址。
只有在重新赋值操作时,才会为变量分配新的内存空间,并将新地址赋值给变量,从而改变列表对象的地址。

综上所述,
对于可变的复杂数据类型,在修改其中的元素或添加、删除元素时,只会改变对象内部元素的地址引用,不会改变对象本身的地址。
只有在重新赋值操作时,才会为变量分配新的内存空间,并改变对象的地址。

1.3 列表复制

在Python中,对于可变的数据类型(如列表),有多种方式可以进行复制。
其中包括使用赋值操作符(=)、分片操作符([:])以及内置的 copy() 函数。

当使用赋值操作符(=)进行复制时,实际上只是创建了一个新的变量,并将该变量指向原始列表的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值