python数据类型可变和不可变_Python 里的 可变类型 vs 不可变类型,浅拷贝 vs 深拷贝...

在python 中可变类型和不可变类型指的是内存地址与其对应的 value 值之间的关系是否可以改变

二者间的关系不可改变的即为不可变类型

不可变类型

字符串,元组,整型,浮点型都是不可变类型

66786eb8-3457-48f0-99b9-cdf0d3e343c5.png!large

如图中地址 XXX01 永远指向 1,XXX02 永远指向 2

☞创建变量

a=1

b=2

则将变量 a 的指针指向 XXX01,b 的指针指向 XXX02,使用内建函数 id() 输出可以看到此时 a 和 b 使用的内存地址不同

ca59d80f-8f97-4b02-9f22-8e8bd78c0b6c.png!large

☞将 b 赋值给 c

b=2

c=b

则将变量 c 的指针也指向 XXX02 (b的内存地址),使用内建函数 id() 输出可以看到此时 b 和 c 使用了同一个内存地址

541907fd-d6f2-4887-9978-fc6cbe0272ab.png!large

☞改变 b 的值

b-=1

b 的值变为 1,b 的指针指向 XXX01 (a 的内存地址),使用内建函数 id() 输出可以看到此时 a 和 b 使用了同一个内存地址

85dcb1aa-6741-48a5-b1ab-2b5184a7a623.png!large

TIPS

当 XXX01 被初次创建并赋值给变量 b 时,它的引用计数被设置为1。当变量 b 赋值给变量 c 时,它的引用计数+1.

可变类型

当内存地址对应的value 值可以更改时即为 可变类型

列表,字典属于可变类型

7c2d6ac9-881e-41d7-b985-bb933fd391cd.png!large

如图中地址 XXX03 XXX04 指向 [1,2,3],也可指向 [1,2,3,4] 或其他不同的值

☞创建变量

m= [1,2,3]

n= [1,2,3]

虽然 m n 的值相同,但 m 的指针指向 XXX03,n 的指针指向 XXX04,使用内建函数 id() 输出可以看到此时 m 和 n 使用的内存地址不同

dc5b2a9a-ebf1-47f5-8812-f9aed26ab398.png!large

☞将 n 赋值给 r

n= [1,2,3]

r=n

变量 r 的指针指向 XXX04 (n 的内存地址),使用内建函数 id() 输出可以看到此时 n 和 r 使用了同一个内存地址

323f5887-8009-4081-b3a2-2c46f4ed6c8c.png!large

☞改变 r 的值

r.append(4)

变量 r 的值变为 [1,2,3,4] 但是 n 的值也发生了改变,n 和 r 仍然指向的是 XXX04 的地址,也就是说 XXX04 对应的 value 值发生了变化

26dea441-2fb9-42d8-8918-f2492c7747bc.png!large

在实际应用中,我们经常会遇到从上游接口获取一个数据 a,将其赋值给 b,然后返回 c,但并不希望 b 在当前接口的变化影响 a,

如果获取的数据类型刚好是可变类型数据,如上述例子的列表,那么在对赋值后的列表处理时,原来的列表数据也对发生改变,显然是不符合我们的期望结果,python 做的还是很强大的,针对这种需求提供了copy 方法,导入后即可调用

import copy

n= [1,2]

r=copy.copy(n) // r=n[:]

变量 r 的指针指向另一个与 n 不同的内存地址,但两者的value 值相同,使用内建函数 id() 输出查看

1a205abe-24f7-4e21-8045-b333f3e42d40.png!large

☞改变 r 的值

r.append(3)

变量 r 的值变为 [1,2,3] , n 的值保持不变,n 和 r 指向不同的内存地址

6f4835a8-578d-4b7a-a5f0-c5da4d007023.png!large

copy 方法有两种:copy.copy() | copy.deepcopy(),顾名思义,一个是浅拷贝,一个是深拷贝

浅拷贝 copy.copy()

Code 标记

import copy

n=[1,2,['a','b']]

r=copy.copy(n)

r.append(3)

r[2].append('c')

print id(n),n

print id(r),r

792feb82-743e-47c3-a20a-555d23c342fd.png!large

浅拷贝没有拷贝子对象 ['a','b'],所以该列表数据改变时的影响是全局的,与前述赋值引用相同

8f28f258-2ff6-4135-90e1-cddf58ded051.png!large

深拷贝 copy.deepcopy()

Code 标记

import copy

n=[1,2,['a','b']]

r=copy.deepcopy(n)

r.append(3)

r[2].append('c')

print id(n),n

print id(r),r

84488682-42dc-44e8-a8a0-dffa44c06201.png!large

深拷贝同时拷贝了父子对象,所以数据改变时只影响拷贝后的数据

3eabfd32-6017-4b0b-a53d-1e49f5b5e5f1.png!large

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值