python源码笔记_python源码学习笔记(一)
(一)python對象的基本實現
眾所周之,python是個極其簡潔高效的腳本語言,其設計思維之簡潔,編寫之簡單,已成公認。想著深入了解內部機制,探索一下源代碼,并記錄一些東西。誠然,人總是健忘的,因而只有不斷地寫日記和筆記記錄自己的想法,我們的有益的想法和生活的點滴才能被永久地保存下來,否者只能在別人思想的軌道上空轉,始終成為不了自己的東西。
當然對于現存的事物,我們最好或者一定要采取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_REFS3 /*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_HEAD31 } PyObject;32
33 typedef struct{34 PyObject_VAR_HEAD35 } 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 inttp_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。
總結
以上是生活随笔為你收集整理的python源码笔记_python源码学习笔记(一)的全部內容,希望文章能夠幫你解決所遇到的問題。