举个例子,根据实际场景的需要,我们要为多个类添加一个 name 属性和一个 say() 方法。显然有多种方法可以实现,但其中一种方法就是使用 MetaClass 元类。不要从字面上去理解元类的含义,事实上 MetaClass 中的 Meta 这个词根,起源于希腊语词汇 meta,包含“超越”和“改变”的意思。
#定义一个元类 class FirstMetaClass(type): # cls代表动态修改的类 # name代表动态修改的类名 # bases代表被动态修改的类的所有父类 # attr代表被动态修改的类的所有属性、方法组成的字典 def __new__(cls, name, bases, attrs): # 动态为该类添加一个name属性 attrs['name'] = "C语言中文网" attrs['say'] = lambda self: print("调用 say() 实例方法") return super().__new__(cls,name,bases,attrs)此程序中,首先可以断定 FirstMetaClass 是一个类。其次,由于该类继承自 type 类,并且内部实现了 __new__() 方法,因此可以断定 FirstMetaCLass 是一个元类。
可以看到,在这个元类的 __new__() 方法中,手动添加了一个 name 属性和 say() 方法。这意味着,通过 FirstMetaClass 元类创建的类,会额外添加 name 属性和 say() 方法。通过如下代码,可以验证这个结论:有关 __new__() 的具体用法,可阅读《Python __new__()方法》一节。
#定义类时,指定元类 class CLanguage(object,metaclass=FirstMetaClass): pass clangs = CLanguage() print(clangs.name) clangs.say()可以看到,在创建类时,通过在标注父类的同时指定元类(格式为
metaclass=元类名
),则当 Python 解释器在创建这该类时,FirstMetaClass 元类中的 __new__ 方法就会被调用,从而实现动态修改类属性或者类方法的目的。
C语言中文网
调用 say() 实例方法
对于 MetaClass 元类,它多用于创建 API,因此我们几乎不会使用到它。
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有