前言
在python的源代码中,PyObject的结构体定义如下,它的内容看起来很简单,只有3项,分别是:_PyObject_HEAD_EXTRA
,ob_refcnt
和ob_type
,其中_PyObject_HEAD_EXTRA是用于指向活动堆的指针,这个我们暂时不用管;ob_refcnt是用于引用计数的,它的类型是long
,记录了当前对象被引用的次数;ob_type是对PyTypeObject类型的一个引用,它也是今天的一个主角,我稍后会在下面重点介绍它的,通过了解它,我相信你会发出类似于“哇!~”的感叹,或者是突然灵光一现的样子:原来是这样子🦆~(如果你也是一个python爱好者的话哈哈哈)
主角—PyObject登场
// object.h
/* Nothing is actually declared to be a PyObject, but every pointer to
* a Python object can be cast to a PyObject*. This is inheritance built
* by hand. Similarly every pointer to a variable-size Python object can,
* in addition, be cast to PyVarObject*.
*/
struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
};
// pytypedefs.h
typedef struct _object PyObject;
在PyObject结构体上方注释有写到:Nothing is actually declared to be a PyObject, but every pointer to a Python object can be cast to a PyObject*. This is inheritance built by hand.
这句话的大概意思就是:任何东西都不会被声明(实例化)为一个PyObject,但是任何指向python对象(int,str,float,dict等等)的指针都可以被映射到PyObject*,这是继承导致的。
看到这里,大家也许想到了一点什么?🤔此时,我们可以回想一下python中一些基础对象类它们的继承关系:如下图所示,通过访问每个类型的__mro__
属性(ps:__mro__的全称是method resolution order
,它记录了方法的调用顺序,也可以理解成类的继承顺序),发现,每一个类型最终都会继承一个object
类,object自己除外;或者直接访问__base__
属性,发现它们返回的也都是object
类,除了object返回的是None。