Python面向对象(三)
Python对象的声明周期,以及周期方法
概念
指对象从诞生到消亡的过程
当一个对象被创建时,会在内存中分配相应的内存空间进行存储
当这个对象不再使用,为了节约内存,就会把这个对象释放
涉及问题
如何监听一个对象的生命过程?
Python如何掌控一个对象的生命?
监听对象生命周期
__new__方法
__init__方法
__del__方法
class Person:
# def __new__(cls, *args, **kwargs):
# print("拦截了")
def __init__(self):
print("初始化")
self.name="sz"
def __del__(self):
print("释放了")
pass
p = Person()
print(p)
print(p.name)
class Person:
__personCount =0
def __init__(self):
print("计数 + 1")
Person.__personCount += 1
# self.__class__.__personCount += 1 也可以
def __del__(self):
print("计数 - 1")
Person.__personCount -= 1
# self.__class__.__personCount -= 1 也可以
@classmethod
def log(cls):
print("当前人的个数是%d个"%Person.__personCount)
p = Person()
p2 = Person()
del p
Person.log()
# 计数 + 1
# 计数 + 1
# 计数 - 1
# 当前人的个数是1个
# 计数 - 1 # 因为最后会调用del释放空间
内存管理机制
-
存储方面
-
在Python中万物皆对象
-
所有对象都会在内存中开辟一块空间进行存储,会根据不同的类型以及内容,开辟不同不同的空间大小进行存储
返回该空间的地址给外界接收(称为"引用"),用于后续对这个对象的操作
可通过
id()
函数获取内存地址(10进制)通过
hex()
函数可以查看对应的16进制地址class Person: pass p = Person() print(p) print(id(p)) print(hex(id(p))) # <__main__.Person object at 0x00000159A2287390> # 1484484277136 # 0x159a2287390
-
对于整数和短小的字符,Python会进行缓存,不会创建多个相同对象
-
容器对象,存储的七大对象,仅仅是对其他对象的引用,并不是其他对象本身
-
-
垃圾回收方面
-
引用计数器
概念:一个对象,会记录着自身被引用的个数
每增加一个引用,这个对象的引用计数会自动+1
每减少一个引用,这个对象的引用计数会自动-1
查看引用计数
import sys sys.getrefcout(对象) # 因为sys.getrefcout又引用了一次,所以会大一
#-----------------引用计算器------------------- import sys class Person: pass p1 = Person() # 1 print(sys.getrefcount(p1)) p2 = p1 # 2 print(sys.getrefcount(p1)) del p2 print(sys.getrefcount(p1)) # 1 del p1 print(sys.getrefcount(p1)) # NameError: name 'p1' is not defined
#-----------引用计数器机制-特殊场景-循环引用问题---------- # 内存管理机制 = 引用计数器机制 + 垃圾回收机制 # 当一个对象, 如果被引用 + 1, 删除一个引用: -1 0: 被自动释放 # 循环引用 # objgraph # objgraph.count() 可以查看,垃圾回收器,跟踪的对象个数 import objgraph class Person: pass class Dog: pass p = Person() d = Dog() print(objgraph.count("Person")) print(objgraph.count("Dog")) p.pet = d d.master = p # 删除p,d之后,对应的对象是否被释放 del p del d print(objgraph.count("Person")) print(objgraph.count("Dog")) # 1 # 1 # 1 # 1 # 并没有被释放,引用计数器的弊端
-
垃圾回收(引用计数器的扩展)
-
主要作用:从经历过“引用计数器机制”仍未被释放的对象中,找到“循环引用”,干掉相关对象
-
底层机制(难 没看懂)
-
垃圾回收时机
-
自动回收
# 1. 自动回收 # 开启垃圾回收机制 # gc.enable # 开启垃圾回收机制(默认开启) # gc.disable # 关闭 # gc.isenabled # 判定是否开启 import gc gc.disable() print(gc.isenabled()) gc.enable() print(gc.isenabled()) # 并且 # 达到了垃圾回收的阈值 # 垃圾回收器中,新增的对象个数和释放的对象个数之差达到某个阈值 # 涉及方法 # gc.get_threshold() 获取自动回收阈值 # gc.set_threshold() 设置自动回收阈值 print(gc.get_threshold())
-
手动回收
# 2. 手动回收 import objgraph import gc class Person: pass class Dog: pass p = Person() d = Dog() p.pet = d d.master = p del p del d gc.collect() #并不关心垃圾回收机制是否开启 print(objgraph.count("Person")) print(objgraph.count("Dog"))
-
-
-