python源码学习笔记(一)
(一)python对象的基本实现
众所周之,python是个极其简洁高效的脚本语言,其设计思维之简洁,编写之简单,已成公认。想着深入了解内部机制,探索一下源代码,并记录一些东西。诚然,人总是健忘的,因而只有不断地写日记和笔记记录自己的想法,我们的有益的想法和生活的点滴才能被永久地保存下来,否者只能在别人思想的轨道上空转,始终成为不了自己的东西。
当然对于现存的事物,我们最好或者一定要采取critica thingking的态度。准备考试,最大的痛苦就是要照抄全搬,头脑越学越死。当时归根到底我们学习不是为了考试,不是为了分数,更重要的是提高自己的capability。
当然对于现存的事物,我们最好或者一定要采取critica thingking的态度。准备考试,最大的痛苦就是要照抄全搬,头脑越学越死。当时归根到底我们学习不是为了考试,不是为了分数,更重要的是提高自己的capability。
python源码的注释很清楚,或者说很人性化,而且事实上也不会出现艰难晦涩的算法,最主要的还是设计的思想和框架。当然宏神马的很讨厌,窜来窜去的...
学习python的第一步就是要了解其工作机制,下面开始记录:
所谓对象,实际上是把一块数据集及针对数据的操作当做为一个整体,非常符合人的思维,比如开关灯,灯、开关就是数据,打开开关就是操作。
首先,python都有个根对象即PyObject, 采用引用计数的方式,当ob_refcnt=0时,从堆中删除对象,释放出内存供别的对象使用。对于可变大小的Object称为PyVarObject, 这样的对象通常都是Container, 在PyObject_VAR_HEAD中有个ob_size这个变量,表明有多少个对象在容器中。具体定义如下
1 [object.h] 2 #ifdef Py_TRACE_REFS 3 /* Define pointers to support a doubly-linked list of all live heap objects. */ 4 #define _PyObject_HEAD_EXTRA \ 5 struct _object *_ob_next; \ 6 struct _object *_ob_prev; 7 8 #define _PyObject_EXTRA_INIT 0, 0, 9 10 #else 11 #define _PyObject_HEAD_EXTRA 12 #define _PyObject_EXTRA_INIT 13 #endif 14 15 /* PyObject_HEAD defines the initial segment of every PyObject. */ 16 #define PyObject_HEAD \ 17 _PyObject_HEAD_EXTRA \ 18 Py_ssize_t ob_refcnt; \ //引用计数 19 struct _typeobject *ob_type; 20 21 #define PyObject_HEAD_INIT(type) \ 22 _PyObject_EXTRA_INIT \ 23 1, type, 24 25 #define PyVarObject_HEAD_INIT(type, size) \ 26 PyObject_HEAD_INIT(type) size, 27 .... 28 29 typedef struct _object { 30 PyObject_HEAD 31 } PyObject; 32 33 typedef struct { 34 PyObject_VAR_HEAD 35 } PyVarObject;
python 中还有一个比较关键的就是类型对象的定义,像C里面有内置的int , double 一样,python 里也需要内置的对象
接着我们会看到_typeobject 的定义
1 [object.h] 2 typedef struct _typeobject{ 3 PyObject_VAR_HEAD //注意这里也有对象头 4 char *tp_name; //for printing 5 int tp_basicsize, tp_itmesize; 6 7 8 //methods 9 destructor tp_dealloc; 10 printfunc tp_print; 11 ..... 12 13 14 //more 15 hashfunc tp_hash; 16 ternaryfunc tp_call; 17 .... 18 19 } PyTypeObject;
与类型相关联的操作信息一般采取函数指针的形式 ,例如 typedef long (*hashfunc)(PyObject *);这些操作分为 标准操作(dealloc, print , compare),标准操作族(numbers, sequences, mappings) 以及其他操作(hash, buff, call)
另外,值得我们注意的是_typeobject也是个对象,其类型为PyType_Type
1 [typeobject.c] 2 3 PyTypeObject PyType_Type ={ 4 PyObject_HEAD_INIT(&PyType_Type) 5 0, 6 "type", 7 sizeof(PyHeadTypeObject), 8 sizeof(PyMemberDef), 9 .... 10 PyObject_GC_Del, 11 (inquiry) type_is_gc, 12 13 }; 14 //以一个整数对象为例: 15 PyTypeObject PyInt_Type = { 16 PyObject_HEAD_INIT(&PyType_Type) 17 0, 18 "int", 19 sizeof(PyIntObject), 20 ... 21 };
紧接着我们会留意到针对PyObject一系列的宏,首先是:
1 #define _Py_NewReference(op) ( \ 2 _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \ 3 _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ 4 Py_REFCNT(op) = 1) 5 6 #define _Py_ForgetReference(op) _Py_INC_TPFREES(op) 7 8 #define _Py_Dealloc(op) ( \ 9 _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \ 10 (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op))) 11 #endif /* !Py_TRACE_REFS */ 12 13 #define Py_INCREF(op) ( \ 14 _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ 15 ((PyObject*)(op))->ob_refcnt++) 16 17 #define Py_DECREF(op) \ 18 do { \ 19 if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ 20 --((PyObject*)(op))->ob_refcnt != 0) \ 21 _Py_CHECK_REFCNT(op) \ 22 else \ 23 _Py_Dealloc((PyObject *)(op)); \ 24 } while (0) 25
第一个是新建对象引用,即初始化ob_refcnt=1,很有意思哈,连comma——','都被宏定义了,然后是丢弃对象引用:
1 #define _Py_INC_TPFREES(OP) dec_count(Py_TYPE(OP))
然后是对对象引用的自增、自减操作。当ob_refcnt=0时,调用析构函数,即tp_dealloc。另外如果OP是个NIL,必须使用Py_XINCREF/Py_XDECREF。基本非常基础的内容,比较浅显,是python设计的开始,和MFC的原理有点类似,PyObject对应CObject。