美文网首页js css htmlPython
Python - metaclass,元类

Python - metaclass,元类

作者: 红薯爱帅 | 来源:发表于2023-03-11 17:50 被阅读0次

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 () {}

相关文章

  • 面试常考(python)

    Python语言特性 1.Python的函数参数传递 2.元类 metaclass metaclass 允许创建类...

  • metaclass

    深刻理解Python中的元类(metaclass) - 文章 - 伯乐在线

  • interview_python

    Python语言特性1 Python的函数参数传递2 Python中的元类(metaclass)3 @static...

  • Python元类metaclass

    最近接触到一个对xml进行序列化的python库,实际上可以理解为一个小的ORM,只不过数据的来源是xml而不是数...

  • Python元类MetaClass

    上文Python中object和type的关系中我们提到元类的概念。type就是最大的一个元类。在这里,我们详细介...

  • Python: 陌生的 metaclass

    原文出处: geekvi 元类 Python 中的元类(metaclass)是一个深度魔法,平时我们可能比较少接触...

  • 理解Python中的元类(metaclass)

    理解Python中的元类(metaclass) 这篇文章基本上是What are metaclasses in P...

  • python基础 -- 元类metaclass

    1. 作用 暂时不深究 2. 操作

  • python:metaclass

    metaclass翻译过来应该是元类的意思。python中一切皆是对象,连类也是对象 而类是元类的实例,默认的cl...

  • Python中的metaclass

    之前一直被Python中的元类困扰,花了点时间去了解metaclass,并记录下我对于元类的理解,这里使用的是Py...

网友评论

    本文标题:Python - metaclass,元类

    本文链接:https://www.haomeiwen.com/subject/xarxldtx.html