编程语言
首页 > 编程语言> > Python中的元类

Python中的元类

作者:互联网

# 在Python中基于类可以创建对象

class Foo:
    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)


# 根据类创建对象
obj = Foo('Miracle')  # 创建这个obj对象 先经过 __new__ 创建对象,然后经过__init__初始化对象

print(obj) # -> <__main__.Foo object at 0x0000017497088880>

对象是基于类创建出来的。那么类是由谁创建的? 类默认是由type创建的。

# 通过type创建一个类
# 参数:类名、继承谁、成员(类属性、和方法)
Boo = type('Coo', (object,), {'name': 'miracle', "func": lambda self: 666})

print(Boo()) # -> <__main__.Coo object at 0x000001796D9AE610>

默认由type创建,怎么让一个类创建的方式改成其他东西呢?使用元类

# Foo类由MyType创建
# Foo是一个对象,由MyType创建,那么他就一定会执行MyType中的__new__方法和__init__方法

class MyType(type):

    def __init__(cls, name, bases, attrs):
        """
        当__new__构造方法执行完之后就会执行该初始化方法
        当class Foo 声明metaclass=MyType时就会调用__init__
        :param name: 类名称 Foo
        :param bases: 继承谁 ()
        :param attrs: 类里面的成员(属性、方法)
            {'__module__': '__main__', '__qualname__': 'Foo',
            '__init__': <function Foo.__init__ at 0x000001F8235AB310>,
            '__new__': <function Foo.__new__ at 0x000001F8236B8700>,
            '__call__': <function Foo.__call__ at 0x000001F8236B80D0>,
            '__classcell__': <cell at 0x000001F8235A8E50: MyType object at 0x000001F8236E2400>}
        """
        super().__init__(name, bases, attrs)

    def __new__(mcs, *args, **kwargs):
        """
        当class Foo 声明metaclass=MyType时就会调用__new__
        mcs等于MyType这个类(也就是元类)
        通过调用它父类type中的__new__方法来创建Foo这个类,然后返回出去
        :param args:
            这个参数就是用type创建类是需要传递的参数
            ('Foo', (), {'__module__': '__main__', '__qualname__': 'Foo'})
        :param kwargs:
        """
        new_cls = super().__new__(mcs, *args, **kwargs)
        print(new_cls)  # -> <class '__main__.Foo'>
        return new_cls

    def __call__(cls, *args, **kwargs):
        """
        call方法是在对象加()是被触发,在这里Foo()就是MyType的对象 那么Foo()就会触发到这里的call
        :param args:
            这里参数接收的就是Foo()括号中的位置参数
        :param kwargs:
            这里参数接收的就是Foo()括号中的关键词参数
        :return:
        """
        # 调用自己那个类的__new__方法也就是Foo的__new__方法来创建对象
        empty_object = cls.__new__(cls, *args, **kwargs)
        # 调用自己那个类的__init__方法也就是Foo的__init__方法来初始化对象
        cls.__init__(empty_object, *args, **kwargs)
        # 返回这个对象也就是返回Foo()这个对象
        return empty_object


class Foo(metaclass=MyType):
    def __init__(self):
        print('Foo init')

    def __new__(cls, *args, **kwargs):
        return super(Foo, cls).__new__(cls)

    def __call__(self, *args, **kwargs):
        # 这里的call在Foo()这个对象 加()后触发
        # 也就是f=Foo()  f()时候触发这里的call
        print('Foo——————call')


标签:__,Python,元类,init,kwargs,new,Foo,cls
来源: https://www.cnblogs.com/miracleeeeeeee/p/16061728.html