python学习笔记:对象,可/不可变对象, +=和=+

对象

先来看一个例子,解释一下python的对象机制

a = 1
print(id(a))
a = 2
print(id(a))

不了解对象的同学可能会觉得,“a=1"的意思是将1赋值给变量a
但是不然,该语句的意思其实是:将变量a指向一个对象,该对象的值为1
也就是说,a只是充当对象的一个引用
再看语句"a=2”,同样地,该语句的意思是:将变量a指向另一个对象,该对象的值为2。并不是把2赋值给a的意思
输出如下,可以看到,a指向的变量的地址改变了。

140736831005072
140736831005104

可能你还是不太明白,那么再举一个列表的栗子

a = [1, 2]
b = a
a.append(1)
print(a, b)   # [1, 2, 1][1, 2, 1]
a = [1, 2, 3, 4]
print(a, b)   # [1, 2, 3, 4] [1, 2, 1]

我们来逐行解释代码

  • 将变量a指向了一个列表对象,值为[1, 2]
  • 将变量b指向了a指向的对象,也就是说现在a, b变量指向同一个对象
  • 修改a指向的对象的值(而不是修改a)
  • 显然,因为a,b指向的对象被修改了(第三步),所以a,b结果相同
  • 将a指向了另一个对象[1, 2, 3, 4](对象[1, 2]并未被修改)
  • 此时b仍指向对象[1, 2, 3]([1, 2]在第三步被修改后变成[1, 2, 3])

因此,我们可以说。

  • 修改一个变量,其实是修改该变量指向的对象
  • 变量其实是对象的一个引用

可变对象与不可变对象

可变对象:对象存放在地址中的值可以被改变
不可变对象:对象存放在地址中的值不可以被改变

  • 典型的可变对象包括list,dict等
  • 典型的不可变对象包括int, float, tuple等

可能你会有疑问,int型变量的值是可以改变的啊?我想让它等于多少就等于多少。
但请注意,这里的可变不可变指的是对象,当你改变int型变量的值时,其实是改变了该变量指向的对象
对于两者的区别,用大白话说就是:可变对象可以在对象的地址不改变的情况下,改变对象的值(如列表中的append()方法)。而不可变对象则不能,如果想修改不可变对象的值,只能选择新建另一个对象

a+=b VS a=a+b

可能你会问,这两个式子有什么区别?最后a的结果不都是a+b嘛?
是的,在算法层面两个式子几乎等价,但在内部机理上有所不同。
首先我们观察,当变量a指向不可变对象时:

a = 1
print(id(a))   # 140736831005072
a += 1
print(id(a))   # 140736831005104
a = a+1
print(id(a))   # 140736831005136

可以看到,3个id(a)均不相同,也就是说,因为a指向了不可变对象,所以+=和=+都会使a指向一个新的对象

接下来,我们看当变量a指向可变对象时:

a = [1]
print(id(a))   # 2692742533576
a += [1]
print(id(a))   # 2692742533576
a = a+[1]
print(id(a))   # 2692773707144

观察到了什么?在a+=[1]后,a指向的对象的地址没有变化。而在=+操作后,却变化了。
也就是说:

  • +=操作其实是对原对象[1]的改变(原地改变)
  • 而=+操作是创造了一个新的[1, 1]对象,并使a指向该对象

关于更深层次的原因,请参阅参考资料1

参考资料

  1. https://www.jianshu.com/p/cada506e19d9
  2. https://blog.csdn.net/rookinzhang/article/details/80259857
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值