type和metaclass元類
阿新 • • 發佈:2018-11-27
元類type
1. 建立類的兩種方式 (都是由type元類建立)
方式一:
class Foo(object): # 預設metaclass = type, 當前類, 由type類建立 a = 'aaa' def func(self, x): return x + 1
方式二:
Foo = type("Foo", (object, ), {'a': "aaa", 'func': lambda self, x: x + 1})
metaclass(元類)
作用:
通過metaclass可以指定當前類由哪一個元類建立
python2和python3的區別:
python3: class Foo(object, metaclass=type): pass python2: class Foo(object): __metaclass__=type pass
自定義元類
1、第一步
class MyType(type): def __init__(self, *args, **kwargs): print("建立類之前") super(MyType, self).__init__(*args, **kwargs) print("建立類之後")
2、第二步
class Base(object, metaclass=MyType): pass
或
Base = MyType('Base', (object, ), {})
這兩部程式碼寫完後,執行:
輸出:
建立類之前
建立類之後
因為: 程式碼一執行, 就建立一個類,由MyType建立Foo類,就執行Mytype的__init__方法了
3、第三步
class Foo(Base): # 基類由MyType建立,Bar也由MyType建立a = 'aaa' def func(self, x): return x + 1
現在有3個類, 執行指令碼,會列印2遍("建立類之前","建立類之後")
元類__new__/__init__/__call__的執行順序
class MyType(type): def __init__(self, *args, **kwargs): print("MyType: __init__") super(MyType, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs): print('MyType: __call__') super(MyType, self).__call__(*args, **kwargs) def with_metaclass(arg): return MyType('Base', (arg,), {}) class Foo(with_metaclass(object)): a = 'aaa' def __init__(self, *args, **kwargs): print('Foo: __init__') super(Foo, self).__init__(*args, **kwargs) def __new__(cls, *args, **kwargs): print('Foo: __new__') return super(Foo, cls).__new__(cls) def func(self, x): return x + 1 b = Foo() # MyType: __init__ 這個是建立Base類的時候執行MyType的__init__ # MyType: __init__ 建立Foo類的時候,執行MyType的__init__ # MyType: __call__ 例項化 Foo(), 先執行MyType的__call__, 再執行Foo的__new__和__init__ # Foo: __new__ 然後才會執行Foo的__new__方法 # Foo: __init__ 最後執行Foo的__init__方法