Python面向对象(三)Python对象的声明周期,以及周期方法

Python对象的声明周期,以及周期方法

概念

指对象从诞生到消亡的过程

当一个对象被创建时,会在内存中分配相应的内存空间进行存储

当这个对象不再使用,为了节约内存,就会把这个对象释放

涉及问题

如何监听一个对象的生命过程?

Python如何掌控一个对象的生命?

监听对象生命周期

  1. __new__方法
  2. __init__方法
  3. __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释放空间

内存管理机制

  • 存储方面

    1. 在Python中万物皆对象

    2. 所有对象都会在内存中开辟一块空间进行存储,会根据不同的类型以及内容,开辟不同不同的空间大小进行存储

      返回该空间的地址给外界接收(称为"引用"),用于后续对这个对象的操作

      可通过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
      
    3. 对于整数和短小的字符,Python会进行缓存,不会创建多个相同对象

    4. 容器对象,存储的七大对象,仅仅是对其他对象的引用,并不是其他对象本身

  • 垃圾回收方面

    1. 引用计数器

      概念:一个对象,会记录着自身被引用的个数

      ​ 每增加一个引用,这个对象的引用计数会自动+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
      # 并没有被释放,引用计数器的弊端
      
    2. 垃圾回收(引用计数器的扩展)

      1. 主要作用:从经历过“引用计数器机制”仍未被释放的对象中,找到“循环引用”,干掉相关对象

      2. 底层机制(难 没看懂)

      3. 垃圾回收时机

        • 自动回收

          # 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"))
          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值