Python对象理解:
官方解释:
1.每个变量都有标识、类型和值。对象一旦创建,它的标识绝不会变;
2.你可以把标识理解为对象在内存中的地址。is 运算符比较两个对象的标识;id() 函数返回对象标识的整数表示
3.值可以改变的对象被称为可变的;值不可以改变的对象就被称为不可变的
对象:
1.实实在在存在的东西,有自己的内存地址【数字、列表、字符串、元组、字典、集合、函数、模块、类、等等】
2.判断变量是否引用同一个对象只能用is或者id()去判断
3.==用来比较两个对象结果相等,因为对象的 __eq__ 方法就是这样实现的
变量:
1.对对象的引用,指向对象内存空间
2.删除变量并非一定删除对象,对象的引用数为0时才回收对象
对象可变与不可变理解【数值类型是否可变】:
1.不可变对象:数值、字符串、元组、集合(frozenset)
2.可变对象:列表、字典、集合(set)
3.可改变与不可变指的是否可以在对象原处改变
4.不可变序列包含可变序列可对可变序列逐个元素更改达到“可变”的目的,不可整体改变可改变序列
对象回收:
1.创建对象也就创建了引用数,当对象不需要时或者说引用数为0时被回收,对象的引用数用sys.getrefcount()函数去返回
2.del删除的是变量引用而不是对象
同一对象测试:
a = [1, 2, 3]
b = [1, 2, 3] # 这里的[1,2,3]非上边的[1,2,3]
print(id(a), id(b)) # 返回标识不同则说明不是一个对象
if a is not b:
print("a is not b")
b = a # 相当变量b引用变量a的对象--->指向同一个对象 【b指向的对象的空间被回收,等待新对象使用】
print(id(a), id(b))
if a is b:
print("a is b")
a[2] = [1, '2'] # 列表的可改变性,原处改变,打印id可以看出来标识符没有改变说明为同一个对象
a.append(8)
c = [1, 2, [1, '2'], 8]
print(id(a), id(b), id(c)) # 内存地址在对象的有效期内不会改变【a,b标识不变】
if a is not c:
print("a is not b")
if a == c:
print("a==c")
D:\mypy\venv\Scripts\python.exe D:/mypy/tmp.py
4055368 3757720
a is not b
4055368 4055368
a is b
4055368 4055368 3931832
a is not b
a==c
Process finished with exit code 0
测试字符串和数字的驻留性:
创建两个数值相等的值给两个变量,只有字符串和数值的这两个变量指向同一个对象
"""
1.驻留:CPython 不会驻留所有字符串和整数,驻留的条件是实现细节,而且没有文档说明
2.处理不可变的对象时,变量保存的是真正的对象还是共享对象的引用无关紧要。如果a==b成立,而且两个对象都不会变,
那么它们就可能是相同的对象。这就是为什么字符串可以安全使用驻留。仅当对象可变时,对象标识才重要
"""
a1 = (1, 2, 3)
b1 = (1, 2, 3)
if a1 is b1:
print("a1 is b1")
a2 = '500'
b2 = '500'
if a2 is b2:
print("a2 is b2")
a3 = [1, 3, '3']
b3 = [1, 3, '3']
if a3 is b3:
print("a3 is b3")
a4 = 1000
b4 = 1000
if a4 is b4:
print("a4 is b4")
D:\mypy\venv\Scripts\python.exe D:/mypy/tmp.py
a2 is b2
a4 is b4
Process finished with exit code 0
对象回收-引用数测试:
"""
def getrefcount(p_object): # real signature unknown; restored from __doc__
getrefcount(object) -> integer
Return the reference count of object. The count returned is generally
one higher than you might expect, because it includes the (temporary)
reference as an argument to getrefcount().
return 0
1.返回对象的引用数,通常大于1高于你的期望值,因为它包含一些临时引用
2.由于调用 __del__() 方法时周边状况已不确定,在其执行期间发生的异常将被忽略,改为打印一个警告到sys.stderr
3.del x并不直接调用x.__del__()---前者会将x的引用计数减一,而后者仅会在x的引用计数变为零时被调用
4.del删除的是引用而不是删除对象,直接调用x.__del__()并不可以删除对象,__del__需要被触发
"""
import sys
class aa:
def __del__(self):
print("del done!")
a = aa() # aa()是实例化的对象 abc皆为变量引用
b = a
c = a
print(id(a), id(b), id(c)) # id一致表示指向同一个对象 此时有3个引用
print(sys.getrefcount(a)) # 打印为4因为这个函数包含了临时引用
del b # 操作完引用数为2,不会触发__del__
del c # 操作完引用数为1,不会触发__del__
del a # 操作完引用数为0,触发__del__
try:
print(a)
except Exception as my_error:
print(my_error)
D:\mypy\venv\Scripts\python.exe D:/mypy/tmp1.py
6641072 6641072 6641072
4
del done!
name 'a' is not defined
Process finished with exit code 0
本文探讨了Python中的对象概念,包括它们的标识、类型和值,强调了可变与不可变对象的区别。详细解释了如何通过is和id()判断对象是否相同,以及如何理解变量作为对象的引用。此外,还介绍了Python的垃圾回收机制,当对象的引用数为0时,对象会被回收。最后,通过实例展示了字符串和数字的驻留性以及引用数在对象回收中的作用。
3557

被折叠的 条评论
为什么被折叠?



