• 类的构造器-init和new


    提到构造器,大家都会想到 __init__,那么__new__是什么?也是构造器。

    init 构造器

    都很熟悉了,直接上代码

    class MyClass(object):
        def __init__(self):
            pass
    
        def m1(self):
            print(3)
    
    mc = MyClass()
    mc.m1()        # 3 

    是不是很简单

    别急,请跟着我的思路,方法m1的参数有个self,这个self就是实例,在调用m1之前这个实例肯定已经产生了;但是init的参数也有个self,在调用init之前,我们并没有实例化,那这个self从何而来呢?new生成的。

    new 构造器

    1. new 和 init 一样都是类的构造器

    2. new在init之前执行,即使没有显示定义

    3. new 必须有返回对象,这个对象就是该类的实例,或者父类的实例(该类继承了一个类),并且是new出来的实例,这个实例的就是self,也就是该类的实例化对象。

    4. new生成的self传给init,如果没有正确返回实例,init将不会执行。

    5. new可以自定义

    6. new是类方法,需要显示的传入类cls作为第一个参数,至少要有这个参数

    7. 新式类中才有new

    8. new和init共用参数,也就是说二者参数形式要一致

    几个例子来验证上面8条。

    代码1

    class A(object):
        def __init__(self,a):
            print "init"
            self.a=a
        def __new__(cls,*args, **kwargs):
            print "new %s"%cls
            print('args:', args)
            return object.__new__(cls, *args, **kwargs)     # 返回当前类的实例
    
    aa=A(3)
    # new <class '__main__.A'>
    # ('args:', (3,))
    # init
    print(aa)       # <__main__.A object at 0x026FC4B0>   
    print(aa.a)     # 3                                   self.a

    1. 新式类,经典类我试了,不行,new没有运行,但不会报错

    2. new 比 init 先执行

    3. new 和 init 共用了参数3

    4. new 返回了当前类的实例,new出来的

    代码2

    class inch(float):
        def __new__(cls, arg=0.0):    # cls 相当于 self
            print(1)
            return float.__new__(cls, arg * 0.0254)
        def __init__(self, aa):
            print('aa:', aa)
            print(2)
    
    a = inch(12)    # new 和 init 公用了参数12
    # 1
    # ('aa:', 12)
    # 2
    print(a)    # 返回的实例就是new的return,父类的实例 float(12*0.0254)
    # 0.3048    =12*0.0254

    1. 该类继承了float类

    2. new 返回了父类float的实例

    3. 该类实例化后其实是new 返回的实例,也就是float(12*0.0254)

    代码3

    class inch2(float):
        def __new__(cls, arg=0.0):    # cls 相当于 self
            print(11)
            return float.__new__(cls, arg)*0.0254           # 返回了父类的实例*0.0254
        def __init__(self,aa):
            print(22)               # 这句没有被执行,因为new没有正确返回父类的实例
    
    a = inch2(12)
    # 11
    print(a)
    # 0.3048    =12*0.0254

    new没有正确返回父类的实例,导致init没有被执行。

  • 相关阅读:
    linux压缩与解压
    simple 单例
    模板字符串
    变量的解构赋值
    let和const关键字
    React的基本认识
    Docker安装Nginx
    jenkins创建工程
    Jenkins系统初始化配置
    在CentOS上使用Docker镜像安装Jenkins
  • 原文地址:https://www.cnblogs.com/yanshw/p/10697235.html
Copyright © 2020-2023  润新知