• 详解python中的__init__与__new__方法


    一、__init__和__new__方法执行的顺序?

    面向对象中介绍了关于对象创建的过程,我们知道__new__方法先于__init__方法执行。

    二、__new__方法是什么?

    首先,我们先来看下下面的代码

    class person(object):
        def __init__(self,name,age):
            self.age=age
            self.name=name
            print('exec init....')
        def __new__(cls, *args,**kwargs):
            print('exec new....')
            return super(person,cls).__new__(cls)
    
    obj1=person('wd',22)
    执行结果:
    exec new....
    exec init....

    上面代码告诉了我们,执行init之前new方法执行了,并且代码中重构了父类的new方法,在上一篇面向对象过程中解释了类创建过程,执行new的过程就是person类创建的过程,所以__new__方法实际上就是创建这个类实例方法。(这里指的是person类)

     说明下上述代码的执行过程:

    1.当解释器解释到obj1=person('wd',22)时候,先执行__new__(cls,*args,**kwargs),并执行父类的__new__方法,将name,age参数传入父类__new__方法,创建person。

    2.类创建完成以后,在调用__init__方法,将wd和22参数传入创建对象。

    三、__init__与__new__的区别

    从上述过程中我们可以发现,这两个方法区别在于:

    1.__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
    2.__new__ 通常用于控制生成一个类实例的过程。它是类级别的方法。

    四、__new__的作用

    依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。
    首先我们来看一下一个功能,自定义类似int类功能,使用int类整数化以后将数变为非负数(大于0)。

    class myint(int):
        def __new__(cls, *args,**kwargs):
            print('exec new....')
            return super(myint,cls).__new__(cls,abs(*args))
    
    print(myint(-1))#自定义int类
    print(int(-1))#自带的int类
    结果:
    exec new....
    1
    -1

    五、通过__new__方法实现单实例

     单例模式,可以简单理解为实例化后生成的每个实例都是完全一样的。

    class Single(object):
        def __new__(cls):
            if not hasattr(cls, 'myinstance'):
                cls.myinstance = super(Single, cls).__new__(cls)
            return cls.myinstance#每次生成的都是同一个实例
    
    
    obj1 = Single()
    obj2 = Single()
    
    obj1.attr1 = 'wd'
    print(obj1.attr1, obj2.attr1)
    print(obj1 is obj2)#返回True表明是同一个实例
    结果:
    wd wd
    True
  • 相关阅读:
    [leetcode]95 Unique Binary Search Trees II (Medium)
    [leetcode] 96 Unique Binary Search Trees (Medium)
    [leetcode] 72. Edit Distance (hard)
    [leetcode] 120. Triangle (Medium)
    [leetcode] 63. Unique Paths II (medium)
    [OpenGL] 不规则区域的填充算法
    [leetcode] 64. Minimum Path Sum (medium)
    ESLint入坑
    报错:for..in loops iterate over the entire prototype chain, which is virtually never what you want.
    vue解决seo优化之预渲染prerender-spa-plugin
  • 原文地址:https://www.cnblogs.com/wdliu/p/6757511.html
Copyright © 2020-2023  润新知