2022-04-26

# 元类

## 1. 先梳理一下

一个类只要继承了`type`类, 就会成为元类: `class MyMeta(type):`, 这说明一个类只要拥有type类中的部分方法或属性, 它就是元类 

2. 只要是类, 不管是类还是元类, 类体中的所有代码就会在定义后会被exec方法执行,放到class_dict中准备传给`type(class_name, class_bases, class_dict)`生成对象或类(类本身也是对象) 

---

1. 类体中的方法内部不会被          执

  2. wef


    2. wef


    | 2q3  | q23r | 2q3r |

     | ---- | ---- | ---- |

     |      |      |      |

     |      | q23r |      |

     |      |      |      |




    行 

    行


    行


        1. e


    2.

  3.

```python

# 运行下面代码:

class MyMeta(type):

    print('my_meta')  # 执行

    def __new__(mcs, *args, **kwargs):

        print('my_meta_new')  # 未执行

        return type.__new__(mcs, *args, **kwargs)

    def __init__(cls, *args, **kwargs):

        print('my_meta_init')  # 未执行

        super().__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):

        print('my_meta_call')  # 未执行

        super().__call__(*args, **kwargs)


# 打印结果:

my_meta

```

当类在定义时指定了元类`metaclass=MyMeta`时,在代码块被加载完成后,会将代码块生成的三个参数`class_name`、`class_bases`、`class_dict`三个参数传给指定的元类进行实例化,生成我们普通的类。即:`type(class_name, class_bases, class_dict)`

```python

class MyMeta(type):

  print('my_meta')  # 1

  def __new__(mcs, *args, **kwargs):

      print('my_meta_new')  # 3

      print(mcs)  # 3 <class '__main__.MyMeta'>

      return type.__new__(mcs, *args, **kwargs)

  def __init__(cls, *args, **kwargs):

      print('my_meta_init')  # 4

      print(cls)  # 4 <class '__main__.MyClass'>

      super().__init__(*args, **kwargs)

  def __call__(cls, *args, **kwargs):

      print('my_meta_call')

      print(cls)

      super().__call__(*args, **kwargs)

```

class MyClass(metaclass=MyMeta):

    print('my_class')  # 2

    def __new__(cls, *args, **kwargs):

        print('my_class_new')

        print(cls)

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


    def __init__(self, *args, **kwargs):

        print('my_class_init')

        print(self)

        super().__init__(*args, **kwargs)


    def __call__(self, *args, **kwargs):

        print('my_class_call')

        print(self)

# 打印结果:

my_meta

my_class

my_meta_new

<class '__main__.MyMeta'>

my_meta_init

<class '__main__.MyClass'>

  ```

```python

class MyMeta(type):

    print('my_meta')  # 1

    def __new__(mcs, *args, **kwargs):

        print('my_meta_new')  # 3

        print(mcs)  # 3 <class '__main__.MyMeta'>

        return type.__new__(mcs, *args, **kwargs)

    def __init__(cls, *args, **kwargs):

        print('my_meta_init')  # 4

        print(cls)  # 4 <class '__main__.MyClass'>

        super().__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):

        print('my_meta_call')  # 5

        print(cls)  # 5 <class '__main__.MyClass'>

        return super().__call__(*args, **kwargs)

class MyClass(metaclass=MyMeta):

    print('my_class')  # 2

    def __new__(cls, *args, **kwargs):

        print('my_class_new')  # 6

        print(cls)  # 6 <class '__main__.MyClass'>

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

    def __init__(self, *args, **kwargs):

        print('my_class_init')  # 7

        print(self)  # 7 <__main__.MyClass object at 0x0000014471934850>

        super().__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):

        print('my_class_call')

        print(self)

c = MyClass()

# 打印结果:

my_meta

my_class

my_meta_new

<class '__main__.MyMeta'>

my_meta_init

<class '__main__.MyClass'>

my_meta_call

<class '__main__.MyClass'>

my_class_new

<class '__main__.MyClass'>

my_class_init

<__main__.MyClass object at 0x0000023C2F604850>

  ```

从上面的结果可以大致看出,一个类被调用时,构造过程:

1. 调用该类的元类为类定义的`__call__` 方法

  这里要注意我的用法,必须是该类的元类,给该类定义的`__call__`方法

  类自己内部定义的`__call__`方法,不管是类方法还是实例方法,都无效,必须是元类中为类定义的,由于元类都继承了type类,所以元类中都会有`__call__`方法 

  这里注意:对象要想变为可调用对象,那么对象的类同样要满足上述条件,即 类在主体代码中要为对象创建`__call__`方法,而对象在生成过程中后追 加的`__call__`方法或属性,均无效 

2. call方法会调用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容