##metaclass是元類## 大部分常見的基礎元類都是type。當輸入一個參數時,type將簡單的返回輸入對象的類型,這就不涉及元類。然而當輸入三個參數時,type將扮演元類的角色,基於輸入參數建立一個類並返回。輸入參數至關簡單:類名,父類及其參數的字典。後面二者能夠爲空,來看一個例子:python
<!-- lang: python --> >>> MyClass = type("MyClass", (object,), {"my_attribute": 0}) >>> type(MyClass) <type 'type'> >>> o = MyClass() >>> o.my_attribute 0
特別注意第二個參數是一個tuple(語法看起來很奇怪,以逗號結尾)。若是你須要在類中安排一個方法,那麼建立一個函數而且將其以屬性的方式傳遞做爲第三個參數,像這樣: <!-- lang: python --> >>> def myclass_init(self, my_attr): ... self.my_attribute = my_attr ...
>>> MyClass = type("MyClass", (object,), {"my_attribute": 0, "init": myclass_init}) >>> o = MyClass("Test") >>> o.my_attribute 'Test' >>> o.init <bound method MyClass.myclass_init of <main.MyClass object at 0x10ab72150>> 咱們能夠經過一個可調用對象(函數或是類)來自定義元類,這個對象須要三個輸入參數並返回一個對象。這樣一個元類在一個類上實現只要定義了它的__metaclass__屬性。第一個例子,讓咱們作一些有趣的事情看看咱們可以用元類作些什麼:
<!-- lang: python --> def Hello(name, parents, attributes): print name, parents, attributes return type(name, parents, attributes)函數
class MM(object): __metaclass__ = Hello def __init__(self): print "hello" if __name__ == '__main__': a = MM() print a
調用順序是:先調用__metaclass__, 而後是__init__。輸出結果爲:
MM (<type 'object'>,) {'module': 'main', 'metaclass': <function Hello at 0x0249F2F0>, 'init': <function init at 0x0249F4B0>} hello <main.MM object at 0x0249BEB0>code