《python源码剖析》笔记 python对象初探

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

1.      在python中,对象就是为C中的结构体在堆上申请的一块内存。对象不能被静态初始化,也不能在栈空间生存。但内建的类型对象都是被静态初始化的。

2.      对象创建后大小不变。可变对象有一指针指向可变大小的内存区域。

3.      对象机制的基石:PyObject

定长对象:

typedef struct _object{
           PyObject_HEAD
}PyObject;

release模式编译-->

typedef struct _object{
           intob_refcnt; // 引用计数,垃圾收集机制
           struct_typeobject *ob_type;// 类型信息,指定对象类型
}PyObject;

PyObject是python对象共有,对象在内存中最开始的字节。

变长对象:

#define PyObject_VAR_HEAD            PyObject_HEAD           intoob_size; // 可变长部分可容纳的元素个数

typedef struct{
           PyObject_VAR_HEAD
}PyVarObject;

在Python内部,每一个对象都拥有相同的对象头部。我们只需要用一个PyObject *指针就可以引用任意的一个对象。

eg:

//PyIntObject对象
typedef struct{
           PyObject_HEAD
           longob_ival; // 保存值
}
//pythonStringObject对象
typedef struct{
           PyObject_VAR_HEAD
           longob_shash;
           into b_sstate;
           charob_sval[1];
} PyStringObject;
//PyListObject对象
typeDef struct{
           PyObject_VAR_HEAD
           PyObjct**ob_item;
           intallocated;
}PyListObject;
//PyDictObject对象
typedef struct{
           Py_ssize_tme_hash;
           PyObject*me_key;
           PyObject*me_value;
}PyDictEntry;

4.      类型对象(_typeobject类型--> 面向对象理论中“类”概念的实现  )

typedef struct _typeobject{
           PyObject_VAR_HEAD//类型对象也是对象,而且是变长对象
           char*tp_name;  //类型的名称,打印时会用到
           inttp_basicsize, tp_itemsize;  //该类型占用内存的大小,分配内存时会用到

           /*与该类型对象相关联的操作信息*/
destructor tp_dealloc;
printfunc tp_print;
//…
} PyTypeObject;

PyType_Type (metaclass), PyInt_Type, PyString_Type,PyDict_Type, PyList_Type是 _typeobject的实例化对象

5.      引用计数

Py_INCREF(op) //增加一个对象的引用计数
Py_DECREF(op) //减少一个对象的引用计数

当引用计数减少到0之后,Py_DECREF将调用该对象的析构函数来释放该对象占有的内存和系统资源。这个析构动作是通过对象对应的类型对象中定义的一个函数指针来指定的,即tp_dealloc

调用析构函数并不意味着最终一定用调用free释放空间,Python中大量采用了内存对象池技术来避免频繁地申请和释放内存空间。

类型对象永远不会被析构。

6.      对象的创建

6.1Python C API(内建类型一般采用这种方式)

//范型的API
PyObject *intObj = PyObject_New(PyObject, &PyInt_Type);
//类型相关的API
PyObject *intObj= PyInt_FromLong(10)

6.2类型对象PyInt_Type (自定义类型只能通过这种方式)

int(10) 就是通过PyInt_Type创建了一个整数对象

所有类都是以object为基类的

tp_new --> 对应C++中的new 操作符,申请内存

tp_init --> 对应C++中的构造函数,完成“初始化”对象的操作

7.      对象的行为

PyTypeObject中定义了大量的函数指针,比如 tp_new, tp_init, tp_dealloc, tp_hash,其中有三组非常重要的操作族

tp_as_number  -->PyNumberMethods

tp_as_sequence --> PySequenceMethods

tp_as_mapping --> PyMappingMethods

typedef PyObject *(*binaryfunc) (PyObject *, PyObject *);
typedef struct{
	binaryfunc nb_add;
	binaryfunc nb_subtract;
	//…
} PyNumberMethods;

typedef struct {
	lenfunc sq_length;
	binaryfunc sq_concat;
	ssizeargfunc sq_repeat;
	ssizeargfunc sq_item;
	ssizessizeargfunc sq_slice;
	ssizeobjargproc sq_ass_item;
	ssizessizeobjargproc sq_ass_slice;
	objobjproc sq_contains;
	/* Added in release 2.0 */
	binaryfunc sq_inplace_concat;
	ssizeargfunc sq_inplace_repeat;
} PySequenceMethods;

typedef struct {
	lenfunc mp_length;
	binaryfunc mp_subscript;
	objobjargproc mp_ass_subscript;
} PyMappingMethods;

8.      类型的类型(PyType_Type)

用户自定义class对应的PyTypeObject是通过PyType_Type创建的。所有class的class都是PyType_Type

PyTypeObject PyType_Type = {
           PyObject_HEAD_INIT(&PyType_Type)
           0,
           “type”,
           //…
};

一般类型对象与PyType_Type对象之间的关系

9.      Python对象的多态性

通过PyObject和PyTypect,Python利用C语言完成了C++所提供的对象的多态的特性。Python内部会用一个PyObject *变量,而不是通过一个PyIntObject *(或者其它具体的类型)来保存来维护这个对象,我们并不知道这个指针所指的对象是什么类型,但可以通过所指对象的ob_type域动态进行判断。

eg.

void Print(PyObject *object){
           object->ob_type->tp_print(object);//根据object的具体类型调用对应的tp_print。一个函数在不同情况下表现出了不同的行为,即多态
}
 

《python源码剖析》笔记 python对象初探

时间: 2024-12-22 00:50:19

《python源码剖析》笔记 python对象初探的相关文章

Python源码剖析笔记3-Python执行原理初探

Python源码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源码剖析笔记,然而慢慢觉得没有从一个宏观的角度理解python执行原理的话,从底向上分析未免太容易让人疑惑,不如先从宏观上对python执行原理有了一个基本了解,再慢慢探究细节,这样也许会好很多.这也是最近这么久没有更新了笔记了,一直在看源码剖析书籍和源码,希望能够从一个宏观层面理清python执行原理.人说读书从薄读厚,再从厚读薄方是理解了

python源码剖析笔记1——Python对象初见

python源码剖析笔记1--Python对象初见 工作整两年了,用python最多,然而对于python内部机制不一定都清楚,每天沉醉于增删改查的简单逻辑编写,实在耗神.很多东西不用就忘记了,比如C语言,正好,python源码用C写的,分析python源码的同时又能温故C语言基础,实在是件很好的事情.另外,还有陈儒大神的<python源码剖析>做指引,分析也不至于没头没脑.期望在一个月的业余时间,能有所小成,以此为记. 1 python中的对象 python中,一切东西都是对象,在c语言实现

Python源码剖析笔记2-Python整数对象

Python源码剖析笔记2-Python整数对象 本文简书地址: http://www.jianshu.com/p/0136ed90cd46 千里之行始于足下,从简单的类别开始分析,由浅入深也不至于自己丧失信心.先来看看Python整数对象,也就是python中的PyIntObject对象,对应的类型对象是PyInt_Type. 1 Python整数对象概览 为了性能考虑,python中对小整数有专门的缓存池,这样就不需要每次使用小整数对象时去用malloc分配内存以及free释放内存.pyth

Python源码剖析笔记0 ——C语言基础

python源码剖析笔记0--C语言基础回顾 要分析python源码,C语言的基础不能少,特别是指针和结构体等知识.这篇文章先回顾C语言基础,方便后续代码的阅读. 1 关于ELF文件 linux中的C编译得到的目标文件和可执行文件都是ELF格式的,可执行文件中以segment来划分,目标文件中,我们是以section划分.一个segment包含一个或多个section,通过readelf命令可以看到完整的section和segment信息.看一个栗子: char pear[40]; static

Python源码剖析笔记4-内建数据类型

Python源码剖析笔记4-内建数据类型 Python内建数据类型包括整数对象PyIntObject,字符串对象PyStringObject,列表对象PyListObject以及字典对象PyDictObject等.整数对象之前已经分析过了,这一篇文章准备分析下余下几个对象,这次在<python源码剖析>中已经写的很详细的部分就不赘述了,主要是总结一些之前看书时疑惑的地方. 1 整数对象-PyIntObject 参见 python整数对象. 2 字符串对象-PyStringObject 2.1

Python源码剖析笔记6-函数机制

Python的函数机制是很重要的部分,很多时候用python写脚本,就是几个函数简单解决问题,不需要像java那样必须弄个class什么的. 本文简书地址:http://www.jianshu.com/p/d00108741a18 1 函数对象PyFunctionObject PyFunctionObject对象的定义如下: typedef struct { PyObject_HEAD PyObject *func_code; /* A code object */ PyObject *func

Python源码剖析笔记5-模块机制

本文简书地址: http://www.jianshu.com/p/14586ec50ab6 python中经常用到模块,比如import xxx,from xxx import yyy这样子,里面的机制也是需要好好探究一下的,这次主要从黑盒角度来探测模块机制,源码分析点到为止,详尽的源码分析见陈儒大神的<python源码剖析>第14章. 1 如何导入模块 首先来看一个导入模块的例子.创建一个文件夹demo5,文件夹中有如下几个文件. [email protected] ~/demo5 $ ls

《python源码剖析》笔记 python中的List对象

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.PyListObject对象 --> 变长可变对象,可看作vector<PyObject *> typedef struct{ PyObject_VAR_HEAD //其中的ob_size表示实际被使用的内存的数量 PyObject **ob_item;//ob_item为指向元素列表的指针,实际上,Python中的list[0]就是ob_item[0] int allocat

《python源码剖析》笔记 python中的Dict对象

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.PyDictObject对象 -->  C++ STL中的map是基于RB-tree的,搜索时间复杂度是O(logN) PyDictObject采用了hash表,时间复杂度是O(1) typedef struct{ Py_ssize_t me_hash; //me_key的hash值,避免每次查询都要重新计算一遍hash值 PyObject *me_key; PyObject *me_