用户定义类型的元类 __new__ 和 __init__ 在哪里被调用?
where does a user-defined type's metaclass' __new__ and __init__ get invoked?
我正在阅读几篇文章以了解如何在 Python (1, 2, 3), and following along Python's source code (typeobject.c) 中创建 class 类型。
我的问题:创建新的用户定义类型时,它的元class' __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
完成时,它 returns type
到 type_call
。然后,type_call
调用 tp_init
- 这意味着调用 type_init
,它调用 object_init
,实际上并没有做任何事情。
在某处,type
的 __new__
和 __init__
应该被调用。我是不是错过了一路上的这些电话,还是他们在type_call
外面打来的?
tp_new
和 tp_init
是 __new__
和 __init__
的 C-level 对应项。对 tp_new
和 tp_init
的调用是 __new__
和 __init__
调用。
如果您在您定义的元类中覆盖 type.__new__
或 type.__init__
,则元类中相应的 tp_new
或 tp_init
插槽将设置为 C-level functions 搜索并调用您的 Python-level 覆盖。
正如 所解释的那样,tp_new
是类型插槽方法,Python-defined 类 的默认版本查找并调用 __new__
方法。
类型槽方法的概念并没有在一个地方得到真正的解释,但请参阅扩展和嵌入文档中的Type Objects in the C API and New Types。
您还需要阅读这两章中关于 tp_new
的具体条目,因为这是一个特别特殊的功能。
如果你想看源码,大部分相关的东西都在typeobject.c
。请注意,__new__
包装器与其他 Python 方法包装器不同,名称查找不会调用通用的特殊方法查找代码,但基础仍然非常相似。
我正在阅读几篇文章以了解如何在 Python (1, 2, 3), and following along Python's source code (typeobject.c) 中创建 class 类型。
我的问题:创建新的用户定义类型时,它的元class' __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
完成时,它 returns type
到 type_call
。然后,type_call
调用 tp_init
- 这意味着调用 type_init
,它调用 object_init
,实际上并没有做任何事情。
在某处,type
的 __new__
和 __init__
应该被调用。我是不是错过了一路上的这些电话,还是他们在type_call
外面打来的?
tp_new
和 tp_init
是 __new__
和 __init__
的 C-level 对应项。对 tp_new
和 tp_init
的调用是 __new__
和 __init__
调用。
如果您在您定义的元类中覆盖 type.__new__
或 type.__init__
,则元类中相应的 tp_new
或 tp_init
插槽将设置为 C-level functions 搜索并调用您的 Python-level 覆盖。
正如 tp_new
是类型插槽方法,Python-defined 类 的默认版本查找并调用 __new__
方法。
类型槽方法的概念并没有在一个地方得到真正的解释,但请参阅扩展和嵌入文档中的Type Objects in the C API and New Types。
您还需要阅读这两章中关于 tp_new
的具体条目,因为这是一个特别特殊的功能。
如果你想看源码,大部分相关的东西都在typeobject.c
。请注意,__new__
包装器与其他 Python 方法包装器不同,名称查找不会调用通用的特殊方法查找代码,但基础仍然非常相似。