Python 面向对象高阶-----metaclass
前言
类也是对象,既然类是对象,那就自然是某个东西的实例化,这个东西就是type
首先看下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 通过传入其他参数也可以实现类的创建
普通方式创建类:
class Foo(object):bar = True
def echo_bar(self):
print(self.bar)
继承关系的方式
class FooChild(Foo):pass
type 方式创建类:
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__ 方法 :对象初始化
以上是 Python 面向对象高阶-----metaclass 的全部内容, 来源链接: utcz.com/z/386643.html