You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中用户自定义类型的元类__new__与__init__调用位置解析

Understanding Where a Metaclass's __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:

  1. Call the metaclass's __new__ to create the class object

    • type_call first fetches the tp_new slot of the metaclass (which maps to type.__new__ for the default type metaclass).
    • 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.
  2. Call the metaclass's __init__ to initialize the class object

    • After __new__ returns a valid object, type_call checks if the returned object is an instance of the metaclass.
    • If it is, it retrieves the tp_init slot (mapping to type.__init__ for the default type), 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.

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_call function in typeobject.c.
  • type_call first invokes the metaclass's __new__ to construct the class object.
  • If the created object is a valid instance of the metaclass, type_call then runs the metaclass's __init__ to initialize the class.

内容的提问来源于stack exchange,提问作者OfirD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:55:13