hechengQAQ

导航

 

一、区别和联系

__new__是构造函数,在创建实例化对象时调用(触发),有一个必要的cls参数,代表当前类,__new__必须要有返回值。
__init__是初始化函数,在创建实例化对象后调用(触发),有一个必要的self参数,代表当前实例对象,__init__不需要有返回值。
总之,两者都在创建实例对象触发,__new__创建实例对象,__init__初始化实例对象的属性

二、__init__和__new__触发效果展示

class Test(object):

     def __new__(cls, *args, **kwargs):
         print("__new__被调用了")
         return super().__new__(cls)

     def __init__(self):
         print("__init__被调用了")
         super(Test,self).__init__()

obj = Test()

__new__被调用了
__init__被调用了

 三、__new__实现单例模式

cls本身没有_instance属性,所以我们声明了一个类属性_instance

class Alone_Model(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return cls._instance

    def __init__(self, name, age):
        self.name = name
        self.age = age

obj = Alone_Model('bang',25)
obj2 = Alone_Model('he',36)
print(obj is obj2)      # True
print(id(obj),id(obj2))  # 内存地址一样
print(obj.name,obj2.name)  # he,he obj2更新了初始化,由于单例模式,obj就是obj2,所以都打印的he,he

 四、__del__

用于在对象被垃圾回收之前执行一些清理工作。当没有任何变量引用一个对象时,该对象就会被垃圾回收机制回收,此时就会自动调用__del__方法。在 Python 中,当使用 del 关键字删除一个对象时,如果该对象存在其他引用,则只会删除这个引用,而不是直接删除该对象本身。如果该对象不存在其他引用,则会立即将其从内存中删除(Python 解释器会自动调用垃圾回收机制来清除该对象的内存)。

在以下情况,__del__会被调用:

  1. 对象的引用计数变为0时,即没有任何变量或其他数据结构引用该对象时。
  2. 程序正常退出时,一些未引用的对象可能会被系统自动回收。
  3. 使用del关键字显式地删除对象时。

例子:

只有真正删除才调用__del__

class MyClass:
    def __init__(self, name):
        self.name = name
        print("Creating object:", self.name)

    def __del__(self):
        print("Deleting object:", self.name)


obj1 = MyClass("Object 1")
obj2 = MyClass("Object 2")
obj3 = obj1

del obj1   # 这时obj1还存在引用,__del__不会调用
del obj2

print("Deleting obj3")
del obj3

"""
打印结果:
Creating object: Object 1
Creating object: Object 2
Deleting object: Object 2
Deleting obj3
Deleting object: Object 1
"""

python垃圾回收策略:

当我们使用del关键字删除一个对象的所有引用时,该对象并不会立即被删除,而是等待垃圾回收。Python的垃圾回收机制采用的是引用计数和分代回收相结合的方式,能够自动处理内存管理。

什么是分代回收?

Python使用了基于引用计数的垃圾回收机制,但是这种方式不能解决循环引用的问题。为了解决这个问题,Python还使用了分代回收机制,即将对象根据其存活时间分为不同的代,并针对各个代采用不同的垃圾回收策略。Python中默认将对象分为三代,分别是0代、1代和2代,每一代都有自己的垃圾回收频率和算法(新创建的对象属于第0代,而第1代和第2代包含了生存时间较长的对象。垃圾回收器会更频繁地检查第0代对象,而对第1代和第2代的检查则较少)。通过这种机制,Python可以更加高效地管理内存空间。

注意点:

在实际开发中,应该尽量避免使用__del__方法,因为它的使用可能会导致一些难以调试的问题。如果需要在对象被销毁时执行一些清理工作,可以考虑使用上下文管理器或者使用atexit模块注册一个回调函数。

 

网络释义
MyClass: 关键字
class MyClass: 性状的使用
posted on 2023-03-24 15:44  hechengQAQ  阅读(24)  评论(0编辑  收藏  举报