• Python构造方法、析构方法和单例模式


    一、__init__()方法

    __init__()通常在初始化一个类实例的时候调用,如:

    class Student(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    
    stu = Student('weiheng',20) #创建一个Student实例,并且对对象属性初始化
    print(stu.name)

    在对象被创建后,调用__init__(),但__init__()其实不是实例化一个类的时候第一个被调用的,当Student()去实例化的时候,第一个被调用的使__new__()方法。

    二、__new__()方法

    class Student(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __new__(cls, *args, **kwargs):
            print('创建一个对象')
            # 创建cls类的一个实例并返回这个实例
            return object.__new__(cls)
    
    
    stu = Student('weiheng',20) #创建一个Student实例,并且对对象属性初始化
    print(stu.name)

    当我们运行代码,会发现__new__()会在__init__()之前执行,其实创建一个对象具体的逻辑是:

    stu = Student('weiheng',20):

    1.首先执行Student()的__new__()方法返回一个Student的一个实例。

    2.通过self来指向Student的一个实例,调用Student的__init__()方法进行对类进行初始化。

    __init__()和__new__()的区别:

    1.__init__()通过实例化一个实例,在类实例被创建之后调用,是一个实例方法;__new__()在实例化的时候调用,创建一个对象并返回这个实例对象

    2.__init__()接收的是普通参数,而__new__()接收的是class,并且返回一个new object。

    三、单例模式:__new__()的应用 

    对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统等。

    如在Window中,只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果所有窗口显示内容完全一致,将会产生重复对象,浪费资源。

    一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。

    1.让类自身保存它的唯一实例

    2.这个类可以保证没有其他实例被创建的,并且它可以提供一个访问该实例的方法

    3.向整个系统提供这个实例

    class Person(object):
        _instance = None
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __new__(cls, *args, **kwargs):
            if not Person._instance:
                Person._instance = object.__new__(cls)
            return Person._instance
    
    
    
    A = Person('zhangsan',30)
    B = Person('zhangsan',30)
    C = Person('wangwu',40)
    
    # instance = None
    # print(bool(instance)) #False
    # print(not instance) #True
    
    #1.
    #创建了两个相同的对象.如果两个对象的内容完全一致的话,将会重复创建,浪费内存空间
    print(id(A))  #1501042099200
    print(id(B))  #1501042099480
    
    #2.
    '''
    1.让类自身保存类的实例
    2.如果类实例不存在的话,就创建,如果存在,就返回已经创建的
    '''
    print(id(A))  #1781445281048
    print(id(C))  #1781445281048

     四、析构函数

    析构函数正好和构造函数相反,当对象结束其生命周期的时候,系统会自动调用其析构函数,析构函数往往用于做一些"善后处理"工作,关闭程序所占用的资源。

    构造函数会为对象开辟一块内存空间,当对象执行完毕后,会调用析构函数进行释放所占用的内存给操作系统。析构函数没有参数也没有返回值。

    '''
    析构函数和沟构造函数相反
    当对象结束其生命周期的时候,系统会自动调用析构函数
    析构函数往往做一些'清理善后'的工作,关闭一些占用的资源
    构造函数创建一块内存空间,对象执行完毕后,会调用析构函数释放内存。
    没有参数,也没有返回值
    '''
    
    class Person(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __new__(cls, *args, **kwargs):
            print('create a new object.')
            return object.__new__(cls)
    
        def __del__(self):
            print('an object of deconstruction.')
    
    zhangsan = Person('zhangsan',30)
    
    #1.被动  当对象执行结束后,系统会自动调用__del__方法
    
    #2.手动  del obj   会手动调用__del__方法,删除对象,回收所占用的资源
    del zhangsan
    
    #会报错 NameErro name 'zhangsan' is not defined
    print(zhangsan)
  • 相关阅读:
    Mybatis如何插入空字段
    为什么要将action实例设置为多例
    hibernate dynamic-update="true"属性不起作用原因(转载)
    查找到匹配的进程并关闭 linux ps -ef
    Mac 下解决修改IntelliJ IDEA 由于修改配置之后无法启动问题
    再聊移动端页面的适配
    重学前端
    前端面试
    使用Flexible实现手淘H5页面的终端适配
    vue-cli3.0 使用px2rem 或 postcss-plugin-px2rem
  • 原文地址:https://www.cnblogs.com/weihengblog/p/8556744.html
Copyright © 2020-2023  润新知