class 实际上是继承于type
而构建一个type,需要三个东西,
- 类的名字
- 它的父类,tuple类型元组
- dict
type() 输入一个参数,返回的是参数的type
type() 输入三个参数,返回的是一个新的type
class A():
pass
A = type("A",(),{})
以上两种写法是完全等价的。
为什么要引入__metaclass__?
因为type()直接调用到C函数里,我们没办法自定义一些中间的过程了。
所以提供给我们一个__metaclass__
的方法,去定义中间的过程。
我们想做这样一件事,
class M(type):
def __new__(cls, name, bases, dict):
return type.__new__(cls, name, bases, dict)
A = M("A",(),{})
让M返回我需要的类。
用metaclass的写法重写一下
class M(type):
def __new__(cls, name, bases, dict):
return type.__new__(cls, name, bases, dict)
class A(metaclass = M):
pass
M的__new__函数是在定义class A的时候执行的
其实还可以往metaclass里放一个__init__函数、一个__call__函数
__init__和__new__的区别就是,init的时候已经有A这个Object了
class M(type):
def __new__(cls, name, bases, dict):
return type.__new__(cls, name, bases, dict)
def __init__(self, name, bases, dict):
return type.__init__(self, name, bases, dict)
def __call__(cls,*args,**kwargs):
return type.__call__(cls, *args, **kwargs)
如果用super().代替type.
在__init__和__call__里需要把self,cls去掉
__new__里面不用去掉
单例模式快速实现
class M(type):
def __call__(cls,*args,**kwargs):
if hasattr(cls,"_instance"):
return cls._instance
cls._instance = type.__call__(cls, *args, **kwargs)
return cls._instance
class A:
__metaclass__ = M
pass
print id(A())
print id(A())