您的位置:首页 > 编程语言 > Python开发

python源码学习笔记(一)

2013-01-10 09:34 393 查看
(一)python对象的基本实现

众所周之,python是个极其简洁高效的脚本语言,其设计思维之简洁,编写之简单,已成公认。想着深入了解内部机制,探索一下源代码,并记录一些东西。诚然,人总是健忘的,因而只有不断地写日记和笔记记录自己的想法,我们的有益的想法和生活的点滴才能被永久地保存下来,否者只能在别人思想的轨道上空转,始终成为不了自己的东西。
当然对于现存的事物,我们最好或者一定要采取critica thingking的态度。准备考试,最大的痛苦就是要照抄全搬,头脑越学越死。当时归根到底我们学习不是为了考试,不是为了分数,更重要的是提高自己的capability。
python源码的注释很清楚,或者说很人性化,而且事实上也不会出现艰难晦涩的算法,最主要的还是设计的思想和框架。当然宏神马的很讨厌,窜来窜去的...
学习python的第一步就是要了解其工作机制,下面开始记录:
所谓对象,实际上是把一块数据集及针对数据的操作当做为一个整体,非常符合人的思维,比如开关灯,灯、开关就是数据,打开开关就是操作。
首先,python都有个根对象即PyObject, 采用引用计数的方式,当ob_refcnt=0时,从堆中删除对象,释放出内存供别的对象使用。对于可变大小的Object称为PyVarObject, 这样的对象通常都是Container, 在PyObject_VAR_HEAD中有个ob_size这个变量,表明有多少个对象在容器中。具体定义如下

[object.h]
#ifdef Py_TRACE_REFS
/* Define pointers to support a doubly-linked list of all live heap objects. */
#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

/* PyObject_HEAD defines the initial segment of every PyObject. */
#define PyObject_HEAD                   \
_PyObject_HEAD_EXTRA                \
Py_ssize_t ob_refcnt;               \            //引用计数
struct _typeobject *ob_type;

#define PyObject_HEAD_INIT(type)        \
_PyObject_EXTRA_INIT                \
1, type,

#define PyVarObject_HEAD_INIT(type, size)       \
PyObject_HEAD_INIT(type) size,
....

typedef struct _object {
PyObject_HEAD
} PyObject;

typedef struct {
PyObject_VAR_HEAD
} PyVarObject;


python 中还有一个比较关键的就是类型对象的定义,像C里面有内置的int , double 一样,python 里也需要内置的对象
接着我们会看到_typeobject 的定义

[object.h]
typedef struct _typeobject{
PyObject_VAR_HEAD            //注意这里也有对象头
char *tp_name;                        //for printing
int tp_basicsize, tp_itmesize;

//methods
destructor tp_dealloc;
printfunc   tp_print;
.....

//more
hashfunc   tp_hash;
ternaryfunc  tp_call;
....

}  PyTypeObject;


与类型相关联的操作信息一般采取函数指针的形式 ,例如 typedef long (*hashfunc)(PyObject *);这些操作分为 标准操作(dealloc, print , compare),标准操作族(numbers, sequences, mappings) 以及其他操作(hash, buff, call)

另外,值得我们注意的是_typeobject也是个对象,其类型为PyType_Type

[typeobject.c]

PyTypeObject PyType_Type ={
PyObject_HEAD_INIT(&PyType_Type)
0,
"type",
sizeof(PyHeadTypeObject),
sizeof(PyMemberDef),
....
PyObject_GC_Del,
(inquiry) type_is_gc,

};
//以一个整数对象为例:
PyTypeObject  PyInt_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"int",
sizeof(PyIntObject),
...
};


紧接着我们会留意到针对PyObject一系列的宏,首先是:

#define _Py_NewReference(op) (                          \
_Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA         \
_Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA               \
Py_REFCNT(op) = 1)

#define _Py_ForgetReference(op) _Py_INC_TPFREES(op)

#define _Py_Dealloc(op) (                               \
_Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA          \
(*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))
#endif /* !Py_TRACE_REFS */

#define Py_INCREF(op) (                         \
_Py_INC_REFTOTAL  _Py_REF_DEBUG_COMMA       \
((PyObject*)(op))->ob_refcnt++)

#define Py_DECREF(op)                                   \
do {                                                \
if (_Py_DEC_REFTOTAL  _Py_REF_DEBUG_COMMA       \
--((PyObject*)(op))->ob_refcnt != 0)            \
_Py_CHECK_REFCNT(op)                        \
else                                            \
_Py_Dealloc((PyObject *)(op));                  \
} while (0)


第一个是新建对象引用,即初始化ob_refcnt=1,很有意思哈,连comma——','都被宏定义了,然后是丢弃对象引用:

#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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: