Python中用户自定义类型的元类__new__与__init__调用位置解析
__new__ and __init__ Are Called When Creating a Custom Class Great question—this gets to the heart of how Python constructs classes under the hood, especially since you're digging into typeobject.c which is where all the core magic happens. Let's break this down step by step, tying it directly back to the type_call function you mentioned.
The Starting Point: Class Definitions as Metaclass Calls
First, remember that when you define a simple class like:
class A(object): pass
Python translates this into an implicit call to the class's metaclass (which defaults to type). In plain terms, it's equivalent to writing:
A = type('A', (object,), {})
This metaclass call is what triggers the execution of type_call in typeobject.c, with the first argument being PyType_Type—the underlying type object for type itself.
Inside type_call: The Sequence of __new__ and __init__
The type_call function is the entry point for calling any type (including metaclasses) to create an instance. For class creation, here's the critical flow:
Call the metaclass's
__new__to create the class objecttype_callfirst fetches thetp_newslot of the metaclass (which maps totype.__new__for the defaulttypemetaclass).- It invokes this
__new__method with the metaclass itself, the class name, base classes, and namespace as arguments. This is where the actual class object (in your example,A) is constructed in memory.
Call the metaclass's
__init__to initialize the class object- After
__new__returns a valid object,type_callchecks if the returned object is an instance of the metaclass. - If it is, it retrieves the
tp_initslot (mapping totype.__init__for the defaulttype), and invokes it with the newly created class object, plus the same name, bases, and namespace arguments. This step sets up any additional state or runs initialization logic defined by the metaclass.
- After
Key Code Snippet from typeobject.c
Here's a simplified version of the type_call function to illustrate this flow clearly:
static PyObject * type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *obj; // Get the metaclass's __new__ method PyObject *new = type->tp_new; if (new == NULL) { PyErr_Format(PyExc_TypeError, "cannot create '%s' instances", type->tp_name); return NULL; } // Call __new__ to create the class object obj = new(type, args, kwds); // Validate the returned object is a valid metaclass instance if (obj != NULL && PyType_IsSubtype(Py_TYPE(obj), type)) { // Get the metaclass's __init__ method PyObject *init = type->tp_init; if (init != NULL) { // Call __init__ to initialize the class object int res = init(obj, args, kwds); if (res < 0) { Py_DECREF(obj); obj = NULL; } } } return obj; }
What Happens with Custom Metaclasses?
If you define a custom metaclass (e.g., class MyMeta(type): ...), the same type_call function remains the entry point. The only difference is that type now refers to your custom metaclass, so type_call will invoke MyMeta.__new__ and MyMeta.__init__ instead of the default type methods.
Example with a Custom Metaclass
class MyMeta(type): def __new__(cls, name, bases, namespace): print(f"MyMeta.__new__ called for class: {name}") return super().__new__(cls, name, bases, namespace) def __init__(cls, name, bases, namespace): print(f"MyMeta.__init__ called for class: {name}") super().__init__(name, bases, namespace) class A(metaclass=MyMeta): pass
When you run this, you'll see __new__ execute first (creating the A class object), followed by __init__ (initializing it)—exactly the sequence controlled by type_call.
Summary
To wrap up:
- Defining a custom class triggers a metaclass call, which routes to the
type_callfunction intypeobject.c. type_callfirst invokes the metaclass's__new__to construct the class object.- If the created object is a valid instance of the metaclass,
type_callthen runs the metaclass's__init__to initialize the class.
内容的提问来源于stack exchange,提问作者OfirD

