《Python高级编程》学习心得——第七章 对象引用、可变性与垃圾回收

《Python高级编程》学习心得——第七章 对象引用、可变性与垃圾回收

本章的内容与我之前写过的一篇博文:python对象赋值、浅复制、深复制的区别十分相关,可以对照着看。

对象可变性

Python中的对象分为可变对象和不可变对象,常见类型中int, str, tuple是不可变对象,list, deque, set是可变对象。可变对象和不可变对象在实现机制上有本质差别。

Python“一切皆对象”,因而Python中的变量是对象的一个引用。这一点与Java不同,Java中仍保留了基本类型如int, float等,Java的int,float变量是直接存储在变量所占的栈空间的。而Python中所有对象都在堆区,栈区的变量是堆区对象的一个引用。

对于不可变对象,我们不可以通过栈区的变量(也就是堆区对象的引用)来直接改变堆区对象的内容,如果我们想要让一个变量指向的堆区对象的内容发生改变,唯一能做的就是在堆区重新开辟一个空间,构造一个新的对象,再将这个对象的赋值给该变量。

a = 1
aid_0 = id(a)				
a = 3
aid_1 = id(a)
print(aid_0 == aid_1)		# False

对于可变对象,我们可以通过栈区的变量来改变堆区对象的内容。

a = [1, 2]
aid_0 = id(a)
a.append(3)
aid_1 = id(a)
print(aid_0 == aid_1)		# True

函数调用时会发生参数传递,但传递的参数仅仅是栈区的引用实参的值拷贝给了栈区的引用形参,因此不可变对象作形参,函数内部对形参改变不会使得函数体外实参的值发生变化,不可变对象的引用无法改变堆区对象的内容;而可变对象作形参,函数内部对形参的改变会改变堆区对象的内容,从而改变实参的值。

x def add(a, b):    a += b	a = 1                       # immutable objectb = 2add(a, b)print(a)                    # 1, unchanged​a = [1]                     # mutable objectb = [2]add(a, b)print(a)                    # [1, 2], changedpython

== 与 is 的区别

一言以蔽之,**==调用的是对象的__eq__**方法,而"a is b"等价于"id(a) == id(b)". 笼统地说,前者是判断两个对象的值是否相同,后者是判断两个对象的内存地址是否相同。

a = [1, 2]
b = a
id(a) == id(b)		# True
a is b				# True
a == b				# True

a = [1, 2]
b = [1, 2]
id(a) == id(b)		# False
a is b				# False
a == b				# True

比较特殊的有两类对象,一类是小整数(不包括大整数)和短字符串,Python内存管理中为小整数和短字符串开辟了一个专门的列表(类似于Java中的字符串常量池),其中每一个地址就对应一个唯一的小整数或短字符串对象,当变量指向每一个小整数或短字符串对象时,只要将该对象在常量池中的地址赋给这个变量即可。因此,多个被赋值为相同的小整数或短字符串的变量id是相等的。

a = 1
b = 1
id(a) == id(b)		# True
a is b				# True

a = 'HIT'
b = 'HIT'
id(a) == id(b)		# True
a is b				# True

a = 300
b = 300
id(a) == id(b)		# False
a is b				# False

另一类是类对象。每个类只有一个全局唯一的类对象。

a = [1, 2]
b = [3, 4]
ac = type(a)
bc = type(b)
id(ac) == id(bc)	# True
ac is bc			# True

del 与 垃圾回收

与C++中的delete关键字会直接回收对象不同,Python的del关键字只会删除对象的引用,Python对象的回收仍由Python的GC(垃圾回收)机制负责。关于Python的垃圾回收机制,又可以引出长篇大论,在此就不节外生枝了。

a = 1
b = a
del a
print(b)			# 1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值