python type metaclass

在python中一切皆对象, 所有类的鼻祖都是type, 也就是所有类都是通过type来创建。

传统创建类

class Foo(object):
    def __init__(self,name):
        self.name = name
  
f = Foo("shuaigaogao")
View Code

 f 是通过 Foo 类实例化的对象,其实,不仅 f 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象,按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

print(type(f))    #输出:<class '__main__.Foo'>  表示:f 对象由Foo类创建
print(type(Foo))  #输出:<class 'type'>          表示:Foo类对象由 type 类创建
所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建 

type创建类

说明:  type创建类的格式,类名 = type('类名',(父类,),{'方法名':方法的内存地址})
def func(self):  #创建方法
    print("hello {0}".format(self.name))
  
def __init__(self,name):  #创建构造方法
    self.name = name
  
Foo = type("Foo",(object,),{"talk":func,"__init__":__init__})  #通过type创建类,如果是经典类的话则写成:Foo = type("Foo",(),{"talk":func,"__init__":__init__})
f = Foo("shuaigaogao")  #创建对象
f.talk()
  
#输出
hello shuaigaogao
View Code

总结:类 是由 type 类 实例化产生的

__new__方法

new方法是类自带的一个方法,可以重构,__new__方法在实例化的时候也会执行,并且先于__init__方法之前执行.

class Foo(object):
  
    def __init__(self,name):
        self.name = name
  
        print("Foo __init__")
  
    def __new__(cls, *args, **kwargs):
        print("Foo __new__",cls, *args, **kwargs)
        return object.__new__(cls)
  
f = Foo("shuaigaogao")
  
#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao  #执行了new方法
Foo __init__  #执行了__init__方法
View Code

new方法作用

作用:所有对象都是通过new方法来实例化的,new里面调用了init方法,所以在实例化的过程中先执行的是new方法,而不是init方法。

①重构__new__方法

class Foo(object):
  
    def __init__(self,name):
        self.name = name
        print("Foo __init__")
  
    def __new__(cls, *args, **kwargs):
        print("Foo __new__",cls, *args, **kwargs)
  
f = Foo("shuaigaogao")  #实例化
  
#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao
View Code

由上面的例子看出,没有执行__init__方法

②重构__new__方法,并继承父类的__new__方法

class Foo(object):
  
    def __init__(self,name):
        self.name = name
  
        print("Foo __init__")
  
    def __new__(cls, *args, **kwargs):   #cls相当于传入类Foo
        print("Foo __new__",cls, *args, **kwargs)
        return object.__new__(cls)  #继承父类的__new__方法,这边必须以返回值的形式继承
  
f = Foo("shuaigaogao")
  
#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao
Foo __init__
View Code

 由上面不难看出,大多数情况下,你都不要去重构你的__new__方法,因为你父类中已经有__new__方法了,已经帮你写好了怎么去创建类,如果你重写的话,就会覆盖父类的里面的__new__方法。但是你重构可以增加一点小功能,但是你覆盖了以后还是需要继承父类回来,要不然你的这个实例就创建不了。

 

使用场景

我想对我自己写的一些类进行定制,就在它实例化之前就进行定制,就可以用到__new__方法,new方法就是用来创建实例的,重构new方法,必须以返回值的形式继承父类的new方法。

①需求:我在创建对象时候,同时创建一个类变量

class Foo(object):
  
    def __init__(self,name):
        self.name = name
  
        print("Foo __init__")
  
    def __new__(cls, *args, **kwargs):  #cls相当于是传入的类名Foo
        cls.name = "shuaigaogao"  #创建对象是定义静态变量
        print(cls.name)
        return object.__new__(cls)  #继承父类的__new__方法
  
f = Foo("shuaigaogao")
print(Foo.name)
View Code

 

__metaclass__方法

metaclass作用

类 是由 type 类实例化产生

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

class MyType(type):
    def __init__(self,*args,**kwargs):
 
        print("Mytype __init__",*args,**kwargs)
 
    def __call__(self, *args, **kwargs):
        print("Mytype __call__", *args, **kwargs)
        obj = self.__new__(self)
        print("obj ",obj,*args, **kwargs)
        print(self)
        self.__init__(obj,*args, **kwargs)
        return obj
 
    def __new__(cls, *args, **kwargs):
        print("Mytype __new__",*args,**kwargs)
        return type.__new__(cls, *args, **kwargs)
 
print('here...')
class Foo(object,metaclass=MyType):
 
    def __init__(self,name):
        self.name = name
 
        print("Foo __init__")
 
    def __new__(cls, *args, **kwargs):
        print("Foo __new__",cls, *args, **kwargs)
        return object.__new__(cls)
 
f = Foo("Alex")
print("f",f)
print("fname",f.name)
View Code

 

执行顺序

类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

 https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python

 

 

 

传统创建类

posted @ 2017-07-19 21:08  sea101  阅读(278)  评论(0编辑  收藏  举报