1. 类没有指定 metaclass 参数
- 执行顺序: 先执行 __new__ 方法,然后再执行 __init__ 方法
class Foo(object):
def __new__(cls, *args, **kwargs):
print(1)
return object.__new__(cls)
def __init__(self):
print(2)
self.name = 'Kevin'
obj = Foo()
2. 类指定了 metaclass 参数
- metaclass 参数的作用: 指定当前类是由谁创建
- 执行顺序:
- 创建类时: 先执行type下的__init__方法
- 实例化对象时: 当一个类实例化时会执行type下的__call__方法,而__call__方法的返回值就是实例化的对象
- __call__方法内部调用:
- 类.__new__ -> 创建对象
- 类.__init__ -> 对象属性的初始化
- 以下面的例子为前提的辅助说明:
- Foo是一个类
- Foo类是MyType的一个“对象”,因为Foo是由MyType所创建的,所以Foo()在实例化的时候会执行MyType下的__call__方法
class MyType(type): # 必须继承type方法,由type方法创建类
def __init__(self, *args, **kwargs):
"""
当创建 Foo 类的时候就会执行当前类的 __init__ 方法(即:type下的__init__方法)
"""
super(MyType, self).__init__(*args, **kwargs) # 调用type类下的__init__方法
def __call__(cls, *args, **kwargs):
"""
当实例化 Foo 类的时候就会执行当前类的 __call__ 方法(即:type下的__call__方法),然后通过 __call__ 方法调用 Foo 类的 __new__ 和 __init__ 方法
:param cls: cls 就是 Foo 类
:return: __call__ 的返回值就是Foo所实例化出来的对象(即:f_obj = 当前类的__call__方法的返回值)
"""
obj = cls.__new__(cls) # 调用 Foo 类下的__new__方法创建对象
cls.__init__(obj, *args, **kwargs) # 调用 Foo 类下的__init__方法初始化对象的属性
return obj # __call__ 的返回值就是Foo所实例化出来的对象(即:f_obj = 当前类的__call__方法的返回值)
class Foo(object, metaclass=MyType):
def __new__(cls, *args, **kwargs):
return object.__new__(cls)
def __init__(self):
self.name = 'Kevin'
f_obj = Foo()
print(f_obj.name) # Kevin
