3月16日学习内容整理:metaclass

1、首先我们要知道:

对象是由类创建的,而类是由type类创建的

所以创建类有两个方法:

class Foo(object):
    pass

# 类名,继承关系,属性
Foo = type('Foo',(object,),{})

上面第一种方法也是默认用type来创建类的,我们就可以理解为类其实就是type的一个对象

当类名()这样加括号的时候,会首先调用type的_ _call_ _方法,在这个方法里会调用类的_ _new_ _方法来创建一个裸着的对象,也就是开辟内存空间,但是没有任何东西,继而继续调用执行类的_ _init_ _方法来给对象封装一些属性

补充一下:对象()这样加括号就会调用类的_ _call_ _方法

 

2、metaclass就可以指定我们自定义的type类,当用类名()时就会从我们定义的metaclass参数值的类中调用_ _call_ _方法,要依次调用_ _new_ _和_ _init_ _方法,返回对象

这样做的一个好处是我们在实例对象时先是_ _new_ _方法再是_ _init_ _方法,用了我们自定义type类的时候我们就可以在new方法和init方法之间就可以做一些操作了

class MyType(type):
    def __init__(self,*args,**kwargs):
        super(MyType,self).__init__(*args,**kwargs)

    def __call__(self, *args, **kwargs):
        obj = self.__new__(self,*args, **kwargs) # object.__init__(....)
        obj.__init__(*args, **kwargs)
        # self.__init__(obj,*args, **kwargs)
        return obj

class Foo(object,metaclass=MyType):
    def __init__(self):
        print('xxx')

# 1. 类是MyType的对象。由MyType(...)
# 2. Foo()
obj = Foo()
print(obj)

 

注意在python2中metaclass的写法不同:

# python3
class Foo(object,metaclass=MyType):
    pass 
        
# python2
class Foo(object):
    __metaclass__ = MyType

 

 

补充:

metaclass的作用:就是用来指定当前类由谁创建,对派生类也是一样的,也就是当父类指定了metaclass以后,它的派生类也得由metaclass指定的类来创建

 

第二种指定metaclass类的方法

class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        print('xxxx')
        return super(MyType, cls).__call__(*args, **kwargs)

# Foo继承的类是由MyType创建的,所以Foo类继承这个创建出来的类,那Foo的metaclass也是MyType
class Foo(MyType('Base', (object,), {})):
    pass
obj = Foo()

 

第三种指定metaclass类的方法

class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        return super(MyType, cls).__call__(*args, **kwargs)


def with_metaclass(base):
    return MyType('XX', (base,), {})

# Foo继承的是with_metaclass函数的返回值,返回值仍是由MyType创建的一个类
# 所以Foo作为创建出来的类的派生类,Foo的metaclass也是MyType
class Foo(with_metaclass(object)):
    pass

 

 

总结:类和对象加括号时的流程

类是type创建的,所以说类就是type的一个对象,而type又是由object创建的

我们创建类的时候实际上就是写type(),那这样的话就会调用object的__call__方法,在这个方法中会调用type的__new__和__init___方法

我们实例类对象时就是写类(),那这样的话就会调用type的__call__方法,在这个方法中会调用类的__new__和__init__方法

posted @ 2018-03-16 19:10  九二零  阅读(92)  评论(0编辑  收藏  举报