用户定义的类型在哪里?元类' __new__和__init__被调用?

时间:2018-04-04 22:29:14

标签: python types cpython

我正在阅读几篇文章,了解如何在Python中创建类类型(123),并遵循Python的源代码(typeobject.c)。

我的问题:当创建新的用户定义类型时,其元类'调用__new____init__

我将解释:

说我们有一个简单的用户定义类型:

class A(object): pass

要创建类型A,最终会调用type_call,并将type作为其第一个参数。在这种情况下,type实际上是PyType_Type

type_call内,调用tp_new,在这种情况下意味着调用type_new

现在,在type_new内,新类型最终分配为:

/* Allocate the type object */
type = (PyTypeObject *)metatype->tp_alloc(metatype, nslots);

type_new完成后,它会将type返回type_call。然后,type_call调用tp_init - 这意味着调用type_init,调用object_init,但实际上并没有做任何事情。

在某处,应调用type' s __new____init__。我一路上是否错过了这些电话,还是在type_call之外打电话?

2 个答案:

答案 0 :(得分:1)

tp_newtp_init__new____init__的C级对应部分。拨打tp_newtp_init 的电话 __new____init__来电。

如果您在定义的元类中覆盖type.__new__type.__init__,则元类中相应的tp_newtp_init个插槽将设置为C级{{3搜索并调用Python级别的覆盖。

答案 1 :(得分:1)

正如Regex101 here所解释的那样,tp_new是类型槽方法,并且Python定义的类的默认版本会查找并调用__new__方法。

类型槽方法的想法并未在一个地方真正解释,但请参阅C API中的user2357112's answer和扩展和嵌入文档中的Type Objects

您还希望在这两章中阅读tp_new上的特定条目,因为它是一项特别特殊的功能。

如果您想查看来源,大部分相关内容都在New Types。请注意,__new__包装器与其他Python方法包装器不同,名称查找不会调用通用的特殊方法查找代码,但基础知识仍然非常相似。