Everything is an object!!!

在解释Python中的object之前,我们应该强调一下不同语境下的表达:Python的底层实现是C语言。C语言是不支持面向对象的;所以在C语言的世界里,不存在类/对象这样的概念,而Python是支持面向对象的,所以,在Python的语境中,我们才可以谈论什么是类,什么是对象。

看下面两篇摘文(需墙):

“Python的世界里一切都是对象”的初衷来源于,设计者希望Python里面的一切都为第一等公民。Python的对象实现是通过C语言的结构体+一系列函数指针实现的。

Common objects

在实现Python的C代码中,有两个最为基础的结构体PyObjectPyVarObject,它们被定义在include/object.h中(一定要看一下该文件中的注释,相当有启发性):

这两个结构体,算是Python的万物之源,剩下所有的结构体(用来实现Python语境中的objects)都来自于这两个结构体,而我们都使用宏定义来使用。

type object

include/object.h">include/object.h中,同时还定义了一个结构体,在Python的语境中叫类型对象。叫PyTypeObject

在该头文件中声明了两个PyTypeObject类型的结构体,而在pythoncore/typeobject.c中进行了定义:

# typeObject.c
PyTypeObject PyType_Type = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,                  /* ob_size */
    "type",                 /* tp_name */
    sizeof(PyHeapTypeObject),       /* tp_basicsize */
    sizeof(PyMemberDef),            /* tp_itemsize */
    (destructor)type_dealloc,       /* tp_dealloc */
    0,                  /* tp_print */
    0,                  /* tp_getattr */
    0,                  /* tp_setattr */
    type_compare,               /* tp_compare */
    (reprfunc)type_repr,            /* tp_repr */
    0,                  /* tp_as_number */
    0,                  /* tp_as_sequence */
    0,                  /* tp_as_mapping */
    (hashfunc)_Py_HashPointer,      /* tp_hash */
    (ternaryfunc)type_call,         /* tp_call */
    0,                  /* tp_str */
    (getattrofunc)type_getattro,        /* tp_getattro */
    (setattrofunc)type_setattro,        /* tp_setattro */
    0,                  /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE,        /* tp_flags */
    type_doc,               /* tp_doc */
    (traverseproc)type_traverse,        /* tp_traverse */
    (inquiry)type_clear,            /* tp_clear */
    0,                  /* tp_richcompare */
    offsetof(PyTypeObject, tp_weaklist),    /* tp_weaklistoffset */
    0,                  /* tp_iter */
    0,                  /* tp_iternext */
    type_methods,               /* tp_methods */
    type_members,               /* tp_members */
    type_getsets,               /* tp_getset */
    0,                  /* tp_base */
    0,                  /* tp_dict */
    0,                  /* tp_descr_get */
    0,                  /* tp_descr_set */
    offsetof(PyTypeObject, tp_dict),    /* tp_dictoffset */
    0,                  /* tp_init */
    0,                  /* tp_alloc */
    type_new,               /* tp_new */
    PyObject_GC_Del,                /* tp_free */
    (inquiry)type_is_gc,            /* tp_is_gc */
};

而在pythoncore/intobject.c中定义了整型类型自己的PyTypeObject结构体:

PyTypeObject PyInt_Type = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,
    "int",
    sizeof(PyIntObject),
    0,
    (destructor)int_dealloc,        /* tp_dealloc */
    (printfunc)int_print,           /* tp_print */
    0,                  /* tp_getattr */
    0,                  /* tp_setattr */
    (cmpfunc)int_compare,           /* tp_compare */
    (reprfunc)int_repr,         /* tp_repr */
    &int_as_number,             /* tp_as_number */
    0,                  /* tp_as_sequence */
    0,                  /* tp_as_mapping */
    (hashfunc)int_hash,         /* tp_hash */
        0,                  /* tp_call */
        (reprfunc)int_repr,         /* tp_str */
    PyObject_GenericGetAttr,        /* tp_getattro */
    0,                  /* tp_setattro */
    0,                  /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
        Py_TPFLAGS_BASETYPE,        /* tp_flags */
    int_doc,                /* tp_doc */
    0,                  /* tp_traverse */
    0,                  /* tp_clear */
    0,                  /* tp_richcompare */
    0,                  /* tp_weaklistoffset */
    0,                  /* tp_iter */
    0,                  /* tp_iternext */
    int_methods,                /* tp_methods */
    0,                  /* tp_members */
    0,                  /* tp_getset */
    0,                  /* tp_base */
    0,                  /* tp_dict */
    0,                  /* tp_descr_get */
    0,                  /* tp_descr_set */
    0,                  /* tp_dictoffset */
    0,                  /* tp_init */
    0,                  /* tp_alloc */
    int_new,                /* tp_new */
    (freefunc)int_free,                 /* tp_free */
};

整型初探

现在有如下结构体:

如果我在执行如下代码:
a = 10
我们看一下,C层面发生了什么事情。
- 首先,为整数10申请一个PyIntObject,其中,ob_ival=10
- PyIntObject中的ob_type是一个结构体指针,指向一个定义好的PyInt_Type,注意PyInt_Type的类型为PyTypeObject
- 而PyInt_Type也是有类型的,所以,指向PyType_Type
- 最后PyType_Type的类型指针指向自身。

其中,PyInt_Type,PyType_Type,PyBaseObject_Type三个结构体的类型都为PyTypeObject。而PyTypeObjectPyIntObject都是来自于最初的PyObject
最后,PyBaseObject_Type我想应该是在后面的类机制中所使用到的,根据手册,所有的PyTypeObjecttp_base都赋值为&PyBaseObject_Type

最后运行时内存各个结构体的关系,如下图:

总结

综上所述:
- 在Python中,一切都是对象,而在底层实现中,不过是C语言结构体和一系列函数指针。
- 要理解底层结构体的关联性。

评论已关闭。

X