Python的实现语言是 ANSI C(标准C语言)。
在Python中,所有的东西都是对象。Python的对象都包含一些相同的内容,这些内容在PyObject中定义,PyObject是整个Python对象机制的核心。
[object.h] typedef struct _object{ PyObject_HEAD //对象头 } PyObject;
宏PyObject_HEAD的实现如下:
/* 定义对象间的双向链表指针,这个不用管,后面会讲到 */ #ifdef Py_TRACE_REFS #define _PyObject_HEAD_EXTRA struct _object *_ob_next; struct _object *_ob_prev; #define _PyObject_EXTRA_INIT 0, 0, #else #define _PyObject_HEAD_EXTRA #define _PyObject_EXTRA_INIT #endif /* 定义对象头 */ #define PyObject_HEAD _PyObject_HEAD_EXTRA //1.额外信息 int ob_refcnt; //2.引用计数 struct _typeobject *ob_type; //3.对象类型
Python对象可分为两种:
类型 | 描述 | 举例 |
---|---|---|
内置对象 | Python自带的对象 | int、string、dict |
自建对象 | 用户自定义的对象 | - |
一般来说,对象是不能被静态初始化的,并且也不能在栈空间上生存。
一个int类型的对象在C中的完整实现如下:
typedef struct t{ PyObject_HEAD //对象头 long ob_ival; //存放int的值 } PyIntObject;
根据“内存分配”规则对Python对象进行分类,可分为两类
分类 | 说明 |
---|---|
不定长对象 | 包含可变长度数据的对象 |
定长对象 | 不包含可变长度数据的对象 |
可变长度数据:像string(C中是n个char)、dict、list这种对象,它的数据长度无法在对象创建前确定它的数据大小。
用于表示可变对象的结构体为PyVarObject(与PyObject同级)
[object.h] #define PyObject_VAR_HEAD PyObject_HEAD int ob_size; /* 可变对象的额外长度 */ typedef struct{ PyObject_VAR_HEAD } PyVarObject;
从PyObject_VAR_HEAD的定义可以看出,PyVarObject只是对PyObject的一个拓展而已。所有Python对象依然拥有相同的对象头部,这就使得在Python中,对对象的引用变得非常的统一,我们只需要一个PyObject * 指针就可以引用任意一个对象。
类型对象结构体_typeobject的定义如下:
[object.h] typedef struct _typeobject{ PyObject_VAR_HEAD char *tp_name; // 1.类型名 int tp_basicsize, tp_itemsize; // 2.创建该类型对象时分配内存空间大小的信息 destructor tp_dealloc; // 3.与该类型对象相关联的操作信息 printfunc tp_print; ...... hashfunc tp_hash; //4.类型的类型信息 ternaryfunc tp_call; } PyTypeObject;
可以看到,类型对象携带的信息可以分成四类
类型名 |
创建对象分配内存空间信息 |
操作信息 |
类型的类型信息 |
第一种是:Python C API;
第二种是: 类型对象 PyXXX_Type。
以创建一个整型对象为例
类型 | 格式 | 整型创建举例 |
---|---|---|
AOL(Abstract Object Layer) | PyObject_XXX | PyObject_New(PyObject, &PtInt_Type) |
COL(Concrete Object Layer) | PyXXX_Type | PyInt_FromLong(10) |
对象的创建分成两步:
【1】创建对象:调用tp_new,对应到 C++的 new操作符。
【2】初始化对象:调用 tp_init, 对应类的构造函数。
python的类型实际上也是一个对象。类习性对象的类型是:
[typeobject.c] PyTypeObject PyType_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ "type", /* tp_name */ sizeof(PyHeapTypeObject), /* tp_basicsize */ sizeof(PyMemberDef), /* tp_itemsize */ ...... }
通过PyObject 和PyTypeObject,Python利用C语言完成了C++所提供的对象的多态的特性。在Python创建一个对象,比如PyIntObject对象时,会分配内存,进行初始化。然后Python内部会用一个PyObject变量,而不是通过一个PyIntObject变量来保存和维护这个对象。其他对象也与次类似,所以在Python内部各个函数之间传递的都是一种泛型指针——PyObject*。这个指针所指的对象究竟是什么类型的,我们不知道,只能从指针所指对象的ob_type域动态进行判断,而正是通过这个域,Python实现了多态机制。
Py_INCREF(op) //引用+1 Py_DECREF(op) //引用-1
Python对象的析构函数 : tp_dealloc 。看
当一个对象的引用计数为0时,Py_DECREF将调用对象的析构函数来释放该对象所占有的内存和系统资源。
Python的对象从概念上大致分为5类
对象类型 | 解释 |
---|---|
Fundamental | 类型对象 |
Numeric | 数值对象 |
Sequence | 容纳其他对象的序列集合对象 |
Mapping | 类似于C++中map的关联对象 |
Internal | Python虚拟机在运行时内部使用的对象 |