¿Por qué PyObject * puede apuntar a cualquier objeto en python?

En el código fuente de python, hay algunas definiciones de macros como esta:

#define PyObject_HEAD \ int ob_refcnt; \ struct _typeobject *ob_type; #define PyObject_VAR_HEAD \ PyObject_HEAD \ int ob_size; typedef struct _object { PyObject_HEAD } PyObject; typedef struct _object { PyObject_HEAD long ob_ival; } PyIntObject; typedef struct { PyObject_VAR_HEAD } PyVarObject; 

La pregunta es, ¿por qué PyObject * puede apuntar a cada objeto (como PyIntObject, PyVarObject) en python?

Cada estructura para los diferentes tipos de objetos de Python tiene una instancia de PyObject_HEAD como su primer miembro (o el primer miembro de su primer miembro, y así sucesivamente).

Se garantiza que este subobjeto miembro se encuentra en la misma dirección que el objeto completo.

PyObject_HEAD* apunta a ese subobjeto miembro, pero se puede convertir al tipo completo una vez que se haya inspeccionado ob_type para determinar cuál es el tipo completo.

Este truco no es exclusivo de CPython; a menudo se usa para implementar un tipo limitado de herencia en C. Básicamente, el modelo de la relación “es una X” por “tiene una X al comienzo de”.

Debido a que PyObject_HEAD es SIEMPRE el primer miembro de la estructura no afectado por el tipo subyacente concreto. El puntero por supuesto será lanzado.