Python 面向对象高阶-----metaclass

Python 面向对象高阶-----metaclass  

 前言

 类也是对象,既然类是对象,那就天然是某个东西的实例化,这个东西就是typepython

首先看下type是怎么回事函数

type

type最经常使用的方法就是查看类型,这只是他的基础用法罢了工具

>>> print(type(1))
<type 'int'>
>>> print(type("1"))
<type 'str'>
>>> print(type(ObjectCreator))
<type 'type'>
>>> print(type(ObjectCreator()))
<class '__main__.ObjectCreator'>

 type 经过传入其余参数也能够实现类的建立spa

普通方式建立类:code

class Foo(object):
    bar = True

    def echo_bar(self):
        print(self.bar)

继承关系的方式对象

class FooChild(Foo):
    pass

type 方式建立类:blog

def echo_bar(self):
    print(self.bar)

Foo = type('Foo', (), {'bar':True, 'echo_bar': echo_bar})

 有继承关系方式继承

FooChild = type('FooChild', (Foo, ), {})

以上两种方法是等效的内存

type 的类建立方式的参数须要三个:字符串

  • 类的名字
  • 一组"类的父类"的元组(tuple) (这个会实现继承,也能够为空)
  • 字典 (类的属性名与值,key-value的形式,不传至关于为空,如通常写法中的pass).

metaclass

说白了,函数 type 就是一个特殊的metaclass.
python在背后使用 type 创造了全部的类。type是全部类的metaclass.

 在python中,一切皆为对象:整数、字符串、函数、类.全部这些对象,都是经过类来创造的.

    >>> age = 35
    >>> age.__class__
    <type 'int'>

    >>> name = 'bob'
    >>> name.__class__
    <type 'str'>

    >>> def foo(): pass
    >>> foo.__class__
    <type 'function'>

    >>> class Bar(object): pass
    >>> b = Bar()
    >>> b.__class__
    <class '__main__.Bar'>

__class____class__则就是由 type 来的了

    >>> age.__class__.__class__
    <type 'type'>
    >>> name.__class__.__class__
    <type 'type'>
    >>> foo.__class__.__class__
    <type 'type'>
    >>> b.__class__.__class__
    <type 'type'>

metaclass就是创造类对象的工具.若是你喜欢,你也能够称之为"类的工厂".

type是python內置的metaclass。不过,你也能够编写本身的metaclass.

指定 metaclass

class Foo(metaclass=MyType):    # python 3 
  # __metaclass__ = MyType    # python 2 
  pass 

流程

Foo中有__metaclass__这个属性吗?

有:

  若是有,会在内存中经过__metaclass__建立一个名字为Foo的类对象。

没有:

  若是没有__metaclass__,它会继续在Bar(父类)中寻找,并尝试作和前面一样的操做。

  若是父类也没有找到__metaclass__,它就会在模块(module)中去寻找__metaclass__,并尝试作一样的操做。

  若是始终都找不到__metaclass__, 最终只能使用内置的type(这也是一个metaclass)来建立这个类对象。

自定义metaclass

 使用metaclass的主要目的,是为了可以在建立类的时候,自动地修改类

 自定义 metaclass 首先就须要自定义一个不一样于 type 的自定义 MyType,可以实现以前的 type 的类建立功能基础上在实现其余想要的功能

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

    def __call__(cls, *args, **kwargs):
        obj = cls.__new__(cls)

        cls.__init__(obj,*args, **kwargs)

        return obj

 

在建立类的时候指定 metaclass 为 自定义的 MyType 便可

class Foo(object,metaclass=MyType):  # metaclass 指定由谁来建立这个类 
    a1 = 123
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        return object.__new__(cls)

    def func(self):
        return 666

 那么在此类建立实例的时候的流程是怎样的呢?

foo = Foo()

 流程

建立类时

先执行 MyType 的 __init__ 方法 ,由super 转向先执行 父类 type 的 __init__ 来建立类

类实例化时

当一个类在实例化时候,先执行 type 的 __call__ 方法 , __call__ 方法 的返回值就是实例化对象

__call__ 内部调用:

  类.__new__ 方法 :建立对象

  类.__init__ 方法 :对象初始化

相关文章
相关标签/搜索