• python 创建实例--待完善


    今天好好琢磨一下 python 创建实例的先后顺序

    一、 就定义一个普通类 Util (默认)继承自 object,覆写 new ,init 方法

    class Util(object):
        def __new__(cls,*args,**kw):
            print('-----Util----__new__ ----start---')
            print('cls: {}'.format(cls))
            print('args: {}'.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
            return object.__new__(cls)
        
        def __init__(self,*args,**kw):
            print('-----Util----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}'.format(args))
            {print(key,'<--->',value,'
    ') for key,value in kw.items()}
            return super(Util,self).__init__()
    args =(1,2,3)
    kw = dict(name='frank',city='changsha')
    util = Util(*args,**kw)
    print(util)
    输出结果:
    -----Util----__new__ ----start---
    cls: <class '__main__.Util'>
    args: (1, 2, 3)
    kw: name <---> frank 
    
    kw: city <---> changsha 
    
    -----Util----__init__ ----start---
    self: <__main__.Util object at 0x7f4d54082a90>
    args: (1, 2, 3)
    name <---> frank 
    
    city <---> changsha 
    
    <class '__main__.Util'>
    

    由上面可以知道 new 优先于 init 执行,如果 __new__ 中没有 return 语句,则不会执行object 的 new 方法,而 init 在 object 中是在 new 中调用的,所以,此刻如下图, Util 中的 init 并不会被调用,只是调用了 Util 类的 new 方法,打印type(util) 得到的是 类类型 --》 NoneType ! 因为 构造方法init 没有被调用,也能理解还没有变为对象啊!!!

    class Util(object):
        def __new__(cls,*args,**kw):
            print('-----Util----__new__ ----start---')
            print('cls: {}'.format(cls))
            print('args: {}'.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
    #         return object.__new__(cls)
        
        def __init__(self,*args,**kw):
            print('-----Util----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}'.format(args))
            {print(key,'<--->',value,'
    ') for key,value in kw.items()}
            return super(Util,self).__init__()
            
            
    args =(1,2,3)
    kw = dict(name='frank',city='changsha')
    util = Util(*args,**kw)
    print(type(util)) 
    结果:
    -----Util----__new__ ----start---
    cls: <class '__main__.Util'>
    args: (1, 2, 3)
    kw: name <---> frank 
    
    kw: city <---> changsha 
    
    <class 'NoneType'>
    
    

    接下来,我们给Util 添加元类,由下图可以看出元类优先于Util 所有方法执行

    class UtilMetaclass(type):
        def __new__(meta_cls,cls,bases,attr_dict):
            print('------UtilMetaclass---__new__ ---start----')
            print('meta_cls: {}'.format(meta_cls))
            print('cls: {}'.format(cls))
            print('bases:{}'.format(bases))
            print('attr_dict: {}
    '.format(attr_dict))
            return type.__new__(meta_cls,cls,bases,attr_dict)
        
    #     def __init__(self,*args,**kw):
    #         print('-----UtilMetaclass----__init__ ----start---')
    #         print('self: {}'.format(self))
    #         print('args: {}
    '.format(args))
    #         {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
    #         return super(UtilMetaclass,self).__init__(*args,**kw)
            
    class Util(object,metaclass=UtilMetaclass):
        def __new__(cls,*args,**kw):
            print('-----Util----__new__ ----start---')
            print('cls: {}'.format(cls))
            print('args: {}'.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
            return object.__new__(cls)
        
        def __init__(self,*args,**kw):
            print('-----Util----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}'.format(args))
            {print(key,'<--->',value,'
    ') for key,value in kw.items()}
            return super(Util,self).__init__()
            
            
    args =(1,2,3)
    kw = dict(name='frank',city='changsha')
    util = Util(*args,**kw)
    print(type(util)) 
    
    输出结果:
    ------UtilMetaclass---__new__ ---start----
    meta_cls: <class '__main__.UtilMetaclass'>
    cls: Util
    bases:(<class 'object'>,)
    attr_dict: {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d540e99d8>, '__new__': <function Util.__new__ at 0x7f4d540e9ea0>}
    
    -----Util----__new__ ----start---
    cls: <class '__main__.Util'>
    args: (1, 2, 3)
    kw: name <---> frank 
    
    kw: city <---> changsha 
    
    -----Util----__init__ ----start---
    self: <__main__.Util object at 0x7f4d5409cb70>
    args: (1, 2, 3)
    name <---> frank 
    
    city <---> changsha 
    
    <class '__main__.Util'>
    

    最后我们来看看给 元类 覆写掉其父类 type 的构造方法,却注释掉return super 语句

    class UtilMetaclass(type):
        def __new__(meta_cls,cls,bases,attr_dict):
            print('------UtilMetaclass---__new__ ---start----')
            print('meta_cls: {}'.format(meta_cls))
            print('cls: {}'.format(cls))
            print('bases:{}'.format(bases))
            print('attr_dict: {}
    '.format(attr_dict))
            return type.__new__(meta_cls,cls,bases,attr_dict)
        
        def __init__(self,*args,**kw):
            print('-----UtilMetaclass----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}
    '.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
            #return super(UtilMetaclass,self).__init__(*args,**kw)
            
    class Util(object,metaclass=UtilMetaclass):
        def __new__(cls,*args,**kw):
            print('-----Util----__new__ ----start---')
            print('cls: {}'.format(cls))
            print('args: {}'.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
            return object.__new__(cls)
        
        def __init__(self,*args,**kw):
            print('-----Util----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}'.format(args))
            {print(key,'<--->',value,'
    ') for key,value in kw.items()}
            return super(Util,self).__init__()
            
            
    args =(1,2,3)
    kw = dict(name='frank',city='changsha')
    util = Util(*args,**kw)
    print(type(util)) 
    输出结果:
    ------UtilMetaclass---__new__ ---start----
    meta_cls: <class '__main__.UtilMetaclass'>
    cls: Util
    bases:(<class 'object'>,)
    attr_dict: {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2ea0>, '__new__': <function Util.__new__ at 0x7f4d542b2488>}
    
    -----UtilMetaclass----__init__ ----start---
    self: <class '__main__.Util'>
    args: ('Util', (<class 'object'>,), {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2ea0>, '__new__': <function Util.__new__ at 0x7f4d542b2488>})
    
    -----Util----__new__ ----start---
    cls: <class '__main__.Util'>
    args: (1, 2, 3)
    kw: name <---> frank 
    
    kw: city <---> changsha 
    
    -----Util----__init__ ----start---
    self: <__main__.Util object at 0x7f4d540f4a20>
    args: (1, 2, 3)
    name <---> frank 
    
    city <---> changsha 
    
    <class '__main__.Util'>
    

    添加上这个 return 语句 其实发现也没什么变化,这就从侧面说明了 new 会调用 init ,而 init 会到继承链(我取的名字)上去找。。。添加上 return 不过是再次调用了 type 的 构造方法罢了,其实没有必要,一般 init 方法中是不需要返回值的这点跟java一样。。。

    class UtilMetaclass(type):
        def __new__(meta_cls,cls,bases,attr_dict):
            print('------UtilMetaclass---__new__ ---start----')
            print('meta_cls: {}'.format(meta_cls))
            print('cls: {}'.format(cls))
            print('bases:{}'.format(bases))
            print('attr_dict: {}
    '.format(attr_dict))
            return type.__new__(meta_cls,cls,bases,attr_dict)
        
        def __init__(self,*args,**kw):
            print('-----UtilMetaclass----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}
    '.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
            return super(UtilMetaclass,self).__init__(*args,**kw)
            
    class Util(object,metaclass=UtilMetaclass):
        def __new__(cls,*args,**kw):
            print('-----Util----__new__ ----start---')
            print('cls: {}'.format(cls))
            print('args: {}'.format(args))
            {print('kw:',key,'<--->',value,'
    ') for key,value in kw.items()}
            return object.__new__(cls)
        
        def __init__(self,*args,**kw):
            print('-----Util----__init__ ----start---')
            print('self: {}'.format(self))
            print('args: {}'.format(args))
            {print(key,'<--->',value,'
    ') for key,value in kw.items()}
            return super(Util,self).__init__()
            
            
    args =(1,2,3)
    kw = dict(name='frank',city='changsha')
    util = Util(*args,**kw)
    print(type(util)) 
    
    输出结果:
    ------UtilMetaclass---__new__ ---start----
    meta_cls: <class '__main__.UtilMetaclass'>
    cls: Util
    bases:(<class 'object'>,)
    attr_dict: {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2d90>, '__new__': <function Util.__new__ at 0x7f4d542b29d8>}
    
    -----UtilMetaclass----__init__ ----start---
    self: <class '__main__.Util'>
    args: ('Util', (<class 'object'>,), {'__module__': '__main__', '__qualname__': 'Util', '__init__': <function Util.__init__ at 0x7f4d542b2d90>, '__new__': <function Util.__new__ at 0x7f4d542b29d8>})
    
    -----Util----__new__ ----start---
    cls: <class '__main__.Util'>
    args: (1, 2, 3)
    kw: name <---> frank 
    
    kw: city <---> changsha 
    
    -----Util----__init__ ----start---
    self: <__main__.Util object at 0x7f4d540f4518>
    args: (1, 2, 3)
    name <---> frank 
    
    city <---> changsha 
    
    <class '__main__.Util'>
    
    class SingletonMetaclass(type):
        def __new__(cls,*args,**kw):
            print('new in SingletonMetaclass start...')
            return super(SingletonMetaclass,cls).__new__(cls,*args,**kw)
        def __init__(self,*args,**kw):
            print('init in SingletonMetaclass start...')
            
        def __call__(cls,*args,**kw):
            print('call in SingletonMetaclass start...')
            if not hasattr(cls,'obj'):
                cls.obj = cls.__new__(cls,*args,**kw)
                cls.__init__(cls.obj,*args,**kw)
            return cls.obj
        
    class Singleton(object,metaclass=SingletonMetaclass):
        def __new__(cls,*args,**kw):
            print('new in Singleton start...')
            return super(Singleton,cls).__new__(cls,*args,**kw)
        
        def __init__(self,*args,**kw):
            print('init in Singleton start...')
            
        def __call__(self,*args,**kw):
            print('call in Singleton start...')
    
    Singleton
    
    s1 = Singleton()
    s2 = Singleton()
    
    s1 == s2
    
    
    如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
  • 相关阅读:
    【原创】【js】screenLeft screenTop screenX screenY属性的有效性和兼容性研究
    兼容兼容兼容:浏览器兼容性大集合
    Vue 打包成APP后首屏出现白屏问题
    uniapp 安卓app端本地打包错误: Not found -1,6 at view.umd.min.js:1
    uniapp 下获取cid
    uniapp fill abort statuscode:-1
    Vuex刷新时数据会消失,那如何解决?为什么还要使用Vuex
    vue 安装失败;vue不是内部或外部命令
    js 文件下载,多个文件下载,pdf下载
    uni-App 去掉顶部导航栏
  • 原文地址:https://www.cnblogs.com/Frank99/p/9342158.html
Copyright © 2020-2023  润新知