Почему PyObject* может указывать на любой объект в Python?

В исходном коде Python есть несколько определений макросов, таких как:

#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;   

Вопрос в том, почему PyObject* может указывать на каждый объект (например, PyIntObject, PyVarObject) в python?

2 ответа

Решение

Каждая структура для различных типов объектов Python имеет экземпляр PyObject_HEAD в качестве первого члена (или первого члена первого члена и т. д.).

Этот подобъект-член гарантированно находится по тому же адресу, что и полный объект.

PyObject_HEAD* указывает на этот дочерний объект, но может быть приведен к полному типу один раз ob_type был проверен, чтобы выяснить, что такое полный тип.

Этот прием не уникален для CPython - он часто используется для реализации ограниченного вида наследования в C. По сути, вы моделируете отношение "является X" с помощью "имеет X в начале".

Так как PyObject_HEAD ВСЕГДА первый член структуры, не затронутый конкретным базовым типом. Указатель, конечно, будет приведен в порядок.

Другие вопросы по тегам