Python MetaClass元类详解

格桑2021-09-18 11:06

    MetaClass元类,本质也是一个类,但和普通类的用法不同,它可以对类内部的定义(包括类属性和类方法)进行动态的修改。可以这么说,使用元类的主要目的就是为了实现在创建类时,能够动态地改变类中定义的属性或者方法。

PythonMetaClass元类详解

    不要从字面上去理解元类的含义,事实上MetaClass中的Meta这个词根,起源于希腊语词汇meta,包含“超越”和“改变”的意思。

    举个例子,根据实际场景的需要,我们要为多个类添加一个name属性和一个say()方法。显然有多种方法可以实现,但其中一种方法就是使用MetaClass元类。

    如果在创建类时,想用MetaClass元类动态地修改内部的属性或者方法,则类的创建过程将变得复杂:先创建MetaClass元类,然后用元类去创建类,最后使用该类的实例化对象实现功能。

    和前面章节创建的类不同,如果想把一个类设计成MetaClass元类,其必须符合以下条件:

    1、必须显式继承自type类;

    2、类中需要定义并实现__new__()方法,该方法一定要返回该类的一个实例对象,因为在使用元类创建类时,该__new__()方法会自动被执行,用来修改新建的类。

    讲了这么多,读者可能对MetaClass元类的功能还是比较懵懂。没关系,我们先尝试定义一个MetaClass元类: 

#定义一个元类
class FirstMetaClass(type):
    # cls代表动态修改的类
    # name代表动态修改的类名
    # bases代表被动态修改的类的所有父类
    # attr代表被动态修改的类的所有属性、方法组成的字典
    def __new__(cls, name, bases, attrs):
        # 动态为该类添加一个name属性
        attrs['name'] = "开课吧广场"
        attrs['say'] = lambda self: print("调用 say() 实例方法")
        return super().__new__(cls,name,bases,attrs)

    此程序中,首先可以断定FirstMetaClass是一个类。其次,由于该类继承自type类,并且内部实现了__new__()方法,因此可以断定FirstMetaCLass是一个元类。

    可以看到,在这个元类的__new__()方法中,手动添加了一个name属性和say()方法。这意味着,通过FirstMetaClass元类创建的类,会额外添加name属性和say()方法。通过如下代码,可以验证这个结论:

#定义类时,指定元类
class CLanguage(object,metaclass=FirstMetaClass):
    pass
clangs = CLanguage()
print(clangs.name)
clangs.say()

  可以看到,在创建类时,通过在标注父类的同时指定元类(格式为metaclass=元类名),则当Python解释器在创建这该类时,FirstMetaClass元类中的__new__方法就会被调用,从而实现动态修改类属性或者类方法的目的。

    运行上面的程序,输出结果为:

开课吧广场
调用 say() 实例方法

    显然,FirstMetaClass元类的__new__()方法动态地为Clanguage类添加了name属性和say()方法,因此,即便该类在定义时是空类,它也依然有name属性和say()方法。

    对于MetaClass元类,它多用于创建API,因此我们几乎不会使用到它。

    以上就是小编为大家准备的“PythonMetaClass元类详解”一文,更多相关内容尽在开课吧广场Python教程频道。

免责声明:本站所提供的内容均来源于网友提供或网络搜集,由本站编辑整理,仅供个人研究、交流学习使用。如涉及版权问题,请联系本站管理员予以更改或删除。
有用
分享