python可变对象与不可变对象

我的python版本:3.8.6

不可变对象immutable:对象内容不可原地改变

不可变的对象有:int、字符串(string)、float、元组(tuple)

a=10
b=a
print(id(a))
print(id(b))
print()
b=11
print(id(a))
print(id(b))
#输出:
#140736928221120
#140736928221120
#
#140736928221120
#140736928221152

可以看到,b=10时它的地址是与a一样的,在b=11后它的地址就变了。python变量都是指针,不可变对象的指针并不是固定地指向一个地址,而是“我的值是10,那我就指向存放10的那个地址,我的值改成11了,那我就指向存放11的那个地址”,原来放10的那个地址依然是10,所以准确地说,变量改变的是指针指向。

值得一说的是,python中有一个小整数的概念,指的是[-5,256]这个区间的整数,它们放在一个small_int的数组里,用户使用这个区间的int的时候系统就会直接从这个数组里引用,所以前后两次执行两次的id()是一样的,而不在这个区间的int(大整数)以及其它不可变对象在程序每次程序执行时都会新分配一个地址,每次执行的id都是随机的。

print(id(257))
#第一次执行:1675989624976
#第二次执行:1865732470928
#第三次执行:1928663681168

至于string对象,python有个intern机制(字符串驻留),它就是一个字典,以字符串为key,以地址为value,每个字符串及其被分配的地址都会放在这个字典里,每次定义字符串对象的时候都会和这个字典比较,有了就直接引用,省点空间,没有就创建。

a='abc'
b='abc'
print(id(a)==id(b))#True

字符串是不可变对象,我们用replace()函数把a的对象’abc’改成’def’,字符串使用replace需要重新赋值,生成一个新的对象,变量a指向这个新对象,而不是原来的’abc’上面做更改。现在知道什么叫‘不可变’了吧。

a='abc'
print(id(a))#2352432259120
a=a.replace('abc','z')
print(id(a))#2352452781232
#两次id不同了,a指向了新的对象
可变对象:对象内容可以原地改变

解释器为每个对象维护不同内存区域,每个可变对象都由解释器重新创建内存空间,并不复用。

可变对象有:字典(dict)、列表(list)、集合(set)

lt1=[1,2,3,4]
lt2=lt1
lt3=[1,2,3,4]
print(id(lt1))#2567070829824
print(id(lt2))#2567070829824
print(id(lt3))#2567070868928
#lt1:新建对象;lt2:引用对象;lt3:新建对象。
lt1.append(100)
print(lt1)#[1, 2, 3, 4, 100]
print(lt2)#[1, 2, 3, 4, 100]
print(lt3)#[1, 2, 3, 4]
print(id(lt1))#2567070829824

lt2只是引用lt1的对象,两者指向同一地址,多个引用,并不是多个对象,其中一个的变化会影响的另外一个。而lt3是一个新对象,尽管它也是[1,2,3,4],但并不因为对象的值相等就指向同一对象,lt1和lt2的变化与lt3无关。

lt1的对象虽然变化了,但变化前后的id并不改变,还是那个地址,这就是‘可变的’对象。

可变对象/不可变对象作为函数参数

可变对象函数参数时,函数内对参数的对象的改变会影响到原始对象;

不可变对象作为参数时,函数内对参数的改变不会影响到原始参数,改变的是函数内变量的指向对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值