类也是对象,既然类是对象,那就天然是某个东西的实例化,这个东西就是typepython
首先看下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 的类建立方式的参数须要三个:字符串
说白了,函数 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.
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 首先就须要自定义一个不一样于 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__ 方法 :对象初始化