Python中元类
元类(metaclass)
简单地说,元类就是一个能创建类的类,而类class 是由type创建的,class可以创建对象
1、type动态创建类:
def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__ """ type(object_or_name, bases, dict) type(object) -> the object's type type(name, bases, dict) -> a new type # (copied from class doc) """ pass
从type源码可以看出,type接受3个参数,第一个是要创建的类名,第二个参数是接受一个tuple(这个类所继承的基类),第三个参数接受一个dict(这个类的属性)
class BaseResource: def check_resource(self): return "base class" def paper_edit(self): return "edit paper..." if __name__ == "__main__": Paper = type( "Paper", (BaseResource,), { "name": "paper_name", "paper_edit": paper_edit } ) paper = Paper() print(paper.check_resource()) print(paper.name) print(paper.paper_edit())
输出:
|
base class |
上例可以看到,使用type创建了Paper类,BaseResource是Paper的基类,paper有name属性和paper_edit方法
2、metaclass控制类对象的生成
对于python中类的实例化过程
(1). 首先寻找类中的metaclass
(2).如果找不到则找其父类的metaclass
(3).如果父类也找不到metaclass,则找其模块中的 如抽象类 找abc模块的 抽象类详见:
(4).在都找不到metaclass的情况下,使用type生成类
class BaseMetaClass(type): def __new__(cls, name, bases, dict_agrs): upper_dict = dict( (arg_name.upper(), arg_val) for arg_name, arg_val in dict_agrs.items() ) return super().__new__(cls, name, bases, upper_dict) class Paper(metaclass=BaseMetaClass): name = "aaa" print("hasattr(Paper, 'name'):{}".format(hasattr(Paper, 'name'))) print("hasattr(Paper, 'NAME'):{}".format(hasattr(Paper, 'NAME')))
BaseMetaClass的父类是type,实现了type的__new__方法,将type()方法的第三个参数(类的属性)做属性名大写转换, Paper类中定义了metaclass,在生成Paper类前会先去执行metaclass,即name="Paper" bases=() dict_agrs = {"name":"aaa"}, dict_agrs 执行大写转换后变成 {"NAME":"aaa"},即:Paper = type("Paper" ,() ,{"NAME":"aaa"})
输出:
|
hasattr(Paper, 'name'):False |
3、使用元类实现单例模式
class SingletonMetaClass(type): __instance = None def __call__(cls, *args, **kwargs): if cls.__instance is None: cls.__instance = super().__call__(*args, **kwargs) print(cls.__instance) return cls.__instance class Singleton(metaclass=SingletonMetaClass): pass singleton1 = Singleton() singleton2 = Singleton() print(id(singleton1)) print(id(singleton2))
Singleton类在生成时先调用SingletonMetaClass,Singleton作为SingletonMetaClass的一个实例,
执行Singleton()时,会调用__call__方法(__call__让实例能像函数一样调用),__call__在Singleton类实例化(__new__和__init)之前调用,执行Singleton2时,直接返回之前存储在类属性cls._instance中的实例。
输出
|
<__main__.Singleton object at 0x7fbd720fd978> |

浙公网安备 33010602011771号