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

如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。
原文地址:https://www.cnblogs.com/Frank99/p/9342158.html