我正在阅读几篇文章,了解如何在Python中创建类类型(1,2,3),并遵循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
之外打电话?
答案 0 :(得分:1)
tp_new
和tp_init
是__new__
和__init__
的C级对应部分。拨打tp_new
和tp_init
的电话 __new__
和__init__
来电。
如果您在定义的元类中覆盖type.__new__
或type.__init__
,则元类中相应的tp_new
或tp_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方法包装器不同,名称查找不会调用通用的特殊方法查找代码,但基础知识仍然非常相似。