1. 概述
在Python中,继承于type的类,称之为元类metaclass。
设置一个class的metaclass为自定义元类MyMeta的话,该class的定义(注意,不是实例化)将由自定义元类MyMeta完成,其生命周期包含:
-
__new__
,解释器调用MyMeta的new方法,来创建Animal和Cat类定义 -
__init__
,解释器调用MyMeta的init方法,来设置Animal或Cat的类属性 -
__del__
,解释器调用MyMeta的del方法,析构Animal和Cat类,而不是类实例,用途不大 -
__call__
,运行时,实例化Animal或Cat时,调用MyMeta的call方法,可用于做唯一实例、实例个数控制等操作
Animal和Cat类实例的构造
、初始化
、析构
等函数,在Animal和Cat类中实现,而不是其元类MyMeta。
2. 示例
from inspect import isfunction
class MyMeta(type):
# 解释器调用metaclass的new方法,来创建Animal和Cat类定义
def __new__(cls, *args, **kwargs):
_class = super().__new__(cls, *args, **kwargs)
if _class.__name__ != 'Animal':
if not hasattr(_class, 'run') or not isfunction(getattr(_class, 'run')):
raise Exception('类{name}没有实现run方法'.format(name=_class.__name__))
print('in meta new', args, kwargs)
return _class
# 解释器调用metaclass的init方法,来设置Animal或Cat的类属性
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.home = 'earth'
print('in meta init', args, kwargs)
# 实例化Animal或Cat时,调用至此
# 可用于做唯一实例、实例个数控制等操作
def __call__(self, *args, **kwds):
instance = super().__call__(*args, **kwds)
print('in meta call', instance)
return instance
# 退出解释器进程时,会析构Animal和Cat类,而不是类实例,用途不大
def __del__(self, *args, **kwargs):
print('in meta del', args, kwargs)
class Animal(metaclass=MyMeta):
def __init__(self, name):
self.name = name
class Cat(Animal):
def __new__(cls, *args, **kwargs):
print('in cat new', cls, args, kwargs)
return super().__new__(cls)
def __init__(self, name):
super().__init__(name)
def run(self):
print('run')
# 类实例的析构
def __del__(self, *args, **kwargs):
print('in cat del', args, kwargs)
print('Animal class property', Animal.home)
print('Cat class property', Cat.home)
print('-'*30)
wild = Animal('wild')
print('Cat instance property', wild.name)
del wild
print('-'*30)
hh = Cat('huahua')
print('Cat instance property', hh.name)
del hh
print('-'*30)
Cat.classmethod_sleep = lambda : print(f'cat is sleeping')
Cat.self_sleep = lambda self: print(f'{self.name} cat is sleeping')
Cat.classmethod_sleep()
Cat('huahua').self_sleep()
print('-'*30)
in meta new ('Animal', (), {'__module__': '__main__', '__qualname__': 'Animal', '__init__': <function Animal.__init__ at 0x7f8dbf223af0>}) {}
in meta init ('Animal', (), {'__module__': '__main__', '__qualname__': 'Animal', '__init__': <function Animal.__init__ at 0x7f8dbf223af0>}) {}
in meta new ('Cat', (<class '__main__.Animal'>,), {'__module__': '__main__', '__qualname__': 'Cat', '__new__': <function Cat.__new__ at 0x7f8dbf223b80>, '__init__': <function Cat.__init__ at 0x7f8dbf223c10>, 'run': <function Cat.run at 0x7f8dbf223ca0>, '__del__': <function Cat.__del__ at 0x7f8dbf223d30>, '__classcell__': <cell at 0x7f8dbf32bc70: MyMeta object at 0x561ced380340>}) {}
in meta init ('Cat', (<class '__main__.Animal'>,), {'__module__': '__main__', '__qualname__': 'Cat', '__new__': <function Cat.__new__ at 0x7f8dbf223b80>, '__init__': <function Cat.__init__ at 0x7f8dbf223c10>, 'run': <function Cat.run at 0x7f8dbf223ca0>, '__del__': <function Cat.__del__ at 0x7f8dbf223d30>, '__classcell__': <cell at 0x7f8dbf32bc70: MyMeta object at 0x561ced380340>}) {}
Animal class property earth
Cat class property earth
------------------------------
in meta call <__main__.Animal object at 0x7f8dbf347820>
Cat instance property wild
------------------------------
in cat new <class '__main__.Cat'> ('huahua',) {}
in meta call <__main__.Cat object at 0x7f8dbf21ba60>
Cat instance property huahua
in cat del () {}
------------------------------
cat is sleeping
in cat new <class '__main__.Cat'> ('huahua',) {}
in meta call <__main__.Cat object at 0x7f8dbf21ba60>
huahua cat is sleeping
in cat del () {}
------------------------------
in meta del () {}
in meta del () {}