類也是對象,既然類是對象,那就天然是某個東西的實例化,這個東西就是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__ 方法 :對象初始化