type和metaclass元类
元类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__方法
总结:
1. 默认类由type实例化创建。
2. 某个类指定metaclass=MyType,那么当前类及所有派生类都由于MyType创建。
3. 实例化对象
- type.__init__
- type.__call__
- 类.__new__
- 类.__init__