元类,类,实例的关系

x是类Foo的一个实例

Foo是type元类的一个实例

type也是type元类的一个实例,所以他是他自己的一个实例


动态定义类

type(参数)  返回参数的类型,通常与对象的__class__属性相同


你也可以传三个参数type(<name>,<bases>,<dct>)调用type()

<name>指定类名,成为__name__的属性

<bases>指定继承类的基类元组,成为__bases__的属性

<dct>指定包含类主体定义的名称空间字典,成为__dct__的属性


自定义元类

重新思考一下先前的这个例子:

表达式Foo()创建一个新的类Foo的实例。当解释器遇到Foo(),将按一下顺序进行解析:

  • 调用Foo父类的__call__()方法。由于Foo是标准的新式类,它的父类是type元类,所以type的__call__()方法被调用。

  • __call__()方法按以下顺序进行调用:

    • __new__()

    • __init__()

如果Foo没有定义__new__()和__init__(),那么将调用Foo父类的默认方法。但是如果Foo定义这些方法,就会覆盖来自父类的方法,这就允许在实例化Foo时可以自定义行为。


这会修改类Foo的实例化行为:每次Foo创建实例时,默认情况下都会将名为attr的属性进行初始化,将该属性设置为100。(类似于这样的代码通常会出现在__init__()方法中,不会出现在__new__()方法里,这个例子仅为演示目的而设计。)

现在,正如前面重申的那样,类也是对象。假设你想类似地在创建类Foo时自定义实例化行为。如果你要遵循上面的模式,则需要再次定义一个自定义方法,并将其指定为类Foo的实例的__new__()方法。Foo是type元类的一个实例,所以代码如下所示:

 阿偶,你可以看到,不能重新指定元类type的__new__()方法。Python不允许这样做。

可以这么讲,type是派生所有新式类的元类。无论如何,你真的不应该去修改它。但是,如果你想自定义一个类的实例化,那么有什么办法呢?

一种可能的解决方案是自定义元类。本质上,不是去试图修改type元类,而是定义自己派生于type的元类,然后对其进行修改。

第一步是定义派生自type的元类,如下:


https://mp.weixin.qq.com/s/HTNRNheuNTLo-Lvmqz46AQ


猜你喜欢

转载自blog.csdn.net/a1057796789/article/details/80376275