Python对象引用,可变性和垃圾回收

博客围绕Python展开,指出变量并非存储数据的盒子,用便利贴来理解更形象。介绍了对象的同一性和相等性,is运算符比较内存地址,==比较对象值。还讲解了浅拷贝,浅拷贝共享内部对象引用,修改可变对象时相关变量会受影响,不可变对象则不受影响。

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

1、变量是标注!不是盒子!

初学py有的教程为了简单理解什么是变量就简单说是存储数据的盒子,其实这是不准确的。

a = [1, 2, 3] # 定义一个列表
b = a   # a和b指向同一个列表
a.append(4) # a里面添加一个元素
print(f'a = {a}')
print(f'b = {b}')
# 输出
# a = [1, 2, 3, 4]
# b = [1, 2, 3, 4]
#   因为a和b指向同一个列表,所以修改a的时候,b也会改变

由上面例子可以发现如果变量是盒子的话,那么是解释不通py的赋值。想象成便利贴更形象。

在这里插入图片描述
   py在内存中要一个空间存放列表[1,2,3],然后咔,贴个标签a,然后在贴个标签b在a上指向的列表。
对象在赋值前就创建了,a=[1,2,3]绑定名称之前对象要存在。

class Gizmo:
    def __init__(self):
        print('Gizmo id: %d' % id(self))   # id()函数返回对象的唯一标识符(整数)

x = Gizmo()
y = Gizmo() * 10
# 输出
Gizmo id: 3139639846384
Gizmo id: 3139639846432  
# 有Id说明创建了一个Gizmo对象,但是后面计算的时候出错终止程序,也就么法赋值给y
Traceback (most recent call last):
  File "c:\Users\****  line 6, in <module>
    y = Gizmo() * 10
 # 右边创建,然后绑定到左边的变量上,贴个标签

同一性,相等性,别名

张三 = {'姓名': '张三', '性别': '男', '特长': '刑法'}
法外狂徒 = 张三     # 张三和法外狂徒指向同一个对象
print(id(张三))     # 2807686055168
print(id(法外狂徒)) # 2807686055168
print(张三 is 法外狂徒)    # True
法外狂徒['特长'] = '法律'  # 张三和法外狂徒指向同一个对象,所以张三和法外狂徒都会改变
print(张三)     # {'姓名': '张三', '性别': '男', '特长': '法律'}

# 假如有个人想冒充张三
李四 = {'姓名': '张三', '性别': '男', '特长': '法律'}
print(张三 == 李四) # True ==判断值是否相等,表面一样
# 如何判断张三和李四是不是同一个人呢?
print(id(张三))     # 2807686055168
print(id(李四))     # 2807686055232
print(张三 is 李四)  # False
# 通过id()函数可以看出张三和李四不是同一个人,因为他们的id不一样
# 通过is关键字也可以看出张三和李四不是同一个人,因为is关键字用来判断两个对象是不是同一个对象,而张三和李四不是同一个对象
  • 对象创建后,内存的地址是不变的,is运算符比较两个内存的地址(标识)。 id()是返回对象标识的整数形式。
  • ==比较对象的值(存储的数据是不是一样)相等性
  • a is b 速度更快因为直接比较整数的id,a==b需要加载一下,调用a.eq(b) 检查同一性。

浅拷贝

浅拷贝共享内部对象的引用
以下代码l1, l2共享 [1, 2, 3], (22, 33, 44)的引用,当修改list1时候list2也会发生变化。

l1 = [4, [1, 2, 3], (22, 33, 44)]
l2 = list(l1)  # 浅拷贝
l1.append(666)
l1[1] += (55, 66) # 列表原地修改不创建新对象
l1[2] += (55, 66) # 元祖不可变 所以需要创建新的对象

在这里在这里插入图片描述
插入图片描述

l2 = list(l1) 由图可以看出l2 和l1共享[1, 2,3]和(22, 33, 44)
分别对list 和tuple进行添加元素
在这里插入图片描述
在list添加55,66的时候是原地改变,因为l1和l2引用的是同一个list所以修改list1,list2也会发生变化。
但是元祖是不可变的,在添加list1对元祖进行修改的时候创建了新的对象,list引用这个新的,list还是引用的原来的所以就没有受到影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值