Python教程

《Python源码剖析》之 Python内建对象

本文主要是介绍《Python源码剖析》之 Python内建对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Python的实现语言是 ANSI C(标准C语言)。

一、对象头部

1、概述

在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 * 指针就可以引用任意一个对象。

在这里插入图片描述

2、类型对象( ob_type)

类型对象结构体_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;
	

可以看到,类型对象携带的信息可以分成四类

类型名
创建对象分配内存空间信息
操作信息
类型的类型信息

3、对象的创建

(1)创建对象的方式

第一种是:Python C API;
第二种是: 类型对象 PyXXX_Type。

以创建一个整型对象为例

类型格式整型创建举例
AOL(Abstract Object Layer)PyObject_XXXPyObject_New(PyObject, &PtInt_Type)
COL(Concrete Object Layer)PyXXX_TypePyInt_FromLong(10)
(2)创建对象的流程

在这里插入图片描述
对象的创建分成两步:
【1】创建对象:调用tp_new,对应到 C++的 new操作符。
【2】初始化对象:调用 tp_init, 对应类的构造函数。

4、类型的类型

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 */
	......
}

5、Python对象的多态性

通过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将调用对象的析构函数来释放该对象所占有的内存和系统资源。

6、概念分类

Python的对象从概念上大致分为5类

对象类型解释
Fundamental类型对象
Numeric数值对象
Sequence容纳其他对象的序列集合对象
Mapping类似于C++中map的关联对象
InternalPython虚拟机在运行时内部使用的对象

在这里插入图片描述

这篇关于《Python源码剖析》之 Python内建对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!