python3.7源码剖析——python对象
學(xué)習(xí)陳儒老師的《Python源碼剖析》
我用的源碼為python3.7,所以做了一些改動(dòng)
PyObject
在python中萬(wàn)物皆對(duì)象,對(duì)象擁有相同的一些內(nèi)容,這些定義在PyObject中
[object.h] typedef struct _object {_PyObject_HEAD_EXTRAPy_ssize_t ob_refcnt;struct _typeobject *ob_type; } PyObject;_PyObject_HEAD_EXTRA宏 其實(shí)在release模式下編譯python不會(huì)定義符號(hào)PyTRACE_REFS
所以 #define _PyObject_HEAD_EXTRA 是空白
那么PyObject就變?yōu)榱?/p> typedef struct _object {Py_ssize_t ob_refcnt;struct _typeobject *ob_type; } PyObject;
Py_ssize_t ob_refcnt 跟python的內(nèi)存管理機(jī)制有關(guān),他實(shí)現(xiàn)了基于引用計(jì)數(shù)的垃圾收集機(jī)制,當(dāng)引用計(jì)數(shù)減少到0時(shí),就可以從堆上被刪除,釋放內(nèi)存
struct _typeobject *ob_type 是一個(gè)指向_typeObject結(jié)構(gòu)體指針,他來(lái)指定一個(gè)對(duì)象類型的類型,因?yàn)槠鋵?shí)相同類型執(zhí)行操作的操作是一樣的,所以放在ob_type所指向的類型對(duì)象的中
當(dāng)然,每個(gè)對(duì)象除了這個(gè)頭還會(huì)有他們特有的一些東西,PyObject對(duì)象里面是別的對(duì)象共有的,因?yàn)閷?duì)于結(jié)構(gòu)體頭部都是這個(gè)的話我們是可以用PyObject*類型的指針輕松訪問(wèn)到任意結(jié)構(gòu)體的頭部信息中的ob_refcnt與ob_type(只要結(jié)構(gòu)體的頭部固定是這些內(nèi)容)那么除了這個(gè)頭部,其他不同的對(duì)象有其他不同的額外東西
[longobject.h] typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ [longintrepr.h] struct _longobject {PyObject_VAR_HEADdigit ob_digit[1]; };對(duì)于整數(shù)來(lái)說(shuō) 他的頭部是一個(gè)變長(zhǎng)對(duì)象的頭部(python3中的整數(shù)沒(méi)有大小限制,所以源碼中不是單純的用int型去存儲(chǔ)他的值,而是用可以變化大小的動(dòng)態(tài)數(shù)組,這個(gè)結(jié)構(gòu)體尾部大小會(huì)在創(chuàng)建的時(shí)候確定大小這里默認(rèn)是1),這個(gè)會(huì)根據(jù)ob_size屬性的大小來(lái)確定大小,ob_size是變成對(duì)象(結(jié)構(gòu)體)擁用的成員
定長(zhǎng)與變長(zhǎng)對(duì)象
對(duì)于變定長(zhǎng)對(duì)象來(lái)說(shuō),他需要的空間是無(wú)法確定的,就是你不可能把他的大小寫死,那么這個(gè)結(jié)構(gòu)體需要分配的存儲(chǔ)數(shù)據(jù)那塊的內(nèi)存大小就是需要根據(jù)實(shí)際對(duì)象的長(zhǎng)度改變的
[object.h] typedef struct {PyObject ob_base; //一個(gè)定長(zhǎng)結(jié)構(gòu)體PyObjectPy_ssize_t ob_size; /* Number of items in variable part */ } PyVarObject;這是變長(zhǎng)對(duì)象的結(jié)構(gòu)體頭部 可以看出來(lái)他的頭部首先是一個(gè)定長(zhǎng)對(duì)象結(jié)構(gòu)體,然后是一個(gè)控制長(zhǎng)度大小的ob_size, 從頭部來(lái)看也就是說(shuō)變長(zhǎng)對(duì)象也是可以通過(guò)PyObject*去訪問(wèn)到ob_refcnt,ob_type這兩個(gè)屬性的,因?yàn)樗麄兊钠屏恳粯?#xff0c;ob_size這個(gè)成員實(shí)際上就是指明了變長(zhǎng)對(duì)象中一共容納了多少元素
類型對(duì)象
[object.h] typedef struct _typeobject {PyObject_VAR_HEADconst char *tp_name; /* For printing, in format "<module>.<name>" */Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation *//* Methods to implement standard operations */destructor tp_dealloc;printfunc tp_print;getattrfunc tp_getattr;setattrfunc tp_setattr;PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)or tp_reserved (Python 3) */reprfunc tp_repr;/* Method suites for standard classes */PyNumberMethods *tp_as_number;PySequenceMethods *tp_as_sequence;PyMappingMethods *tp_as_mapping;...... #ifdef COUNT_ALLOCS/* these must be last and never explicitly initialized */Py_ssize_t tp_allocs;Py_ssize_t tp_frees;Py_ssize_t tp_maxalloc;struct _typeobject *tp_prev;struct _typeobject *tp_next; #endif } PyTypeObject;PyObject_VAR_HEAD 宏
#define PyObject_VAR_HEAD PyVarObject ob_base;可以看出來(lái) type_object對(duì)象是一個(gè)變長(zhǎng)對(duì)象的頭部,也就是說(shuō)它具備ob_size成員,且與PyVarObject一樣頭部可以用PyObject*訪問(wèn)ob_refcnt, *ob_type
對(duì)象的行為
[object.h] typedef struct _typeobject {PyObject_VAR_HEADconst char *tp_name; /* For printing, in format "<module>.<name>" */Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation *//* Methods to implement standard operations */destructor tp_dealloc;printfunc tp_print;getattrfunc tp_getattr;setattrfunc tp_setattr;PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)or tp_reserved (Python 3) */reprfunc tp_repr;/* Method suites for standard classes */PyNumberMethods *tp_as_number;PySequenceMethods *tp_as_sequence;PyMappingMethods *tp_as_mapping;...... } PyTypeObject; PyNumberMethods *tp_as_number; PySequenceMethods *tp_as_sequence; PyMappingMethods *tp_as_mapping;可以從名字上看出這三個(gè)方法分別是作為數(shù)字的方法,作為序列的方法,作為字典的方法
這也是為什么在python中其實(shí)只要我們實(shí)現(xiàn)了特定的方法就可以獲得序列的操作,比如實(shí)現(xiàn)__add__方法可以實(shí)現(xiàn)加法,__getitem__可以實(shí)現(xiàn)序列的相關(guān)操作
類型的類型
因?yàn)镻yTypeObject的頭部是一個(gè)PyObject_VAR_HEAD(PyVarObject ob_base)說(shuō)明它的最頭部還嵌套了一個(gè)(PyObject),而PyObject類型里面有一個(gè)ob_type指針指向一個(gè)PyTypeObject
[object.h] typedef struct _object {_PyObject_HEAD_EXTRAPy_ssize_t ob_refcnt;struct _typeobject *ob_type; } PyObject;類型的類型也就是ob_type指向的還是一個(gè)PyTypeObject,下面是他指向的結(jié)構(gòu)體,里面初始化了一些數(shù)據(jù)
[typeobject.c] PyTypeObject PyType_Type = {PyVarObject_HEAD_INIT(&PyType_Type, 0)"type", /* tp_name */sizeof(PyHeapTypeObject), /* tp_basicsize */sizeof(PyMemberDef), /* tp_itemsize */(destructor)type_dealloc, /* tp_dealloc ... };頭部的宏
#define PyObject_HEAD_INIT(type) \{ _PyObject_EXTRA_INIT \1, type },#define PyVarObject_HEAD_INIT(type, size) \{ PyObject_HEAD_INIT(type) size },可以看出來(lái)是初始化了PyVarObject頭部的值,默認(rèn)為
{{ _PyObject_EXTRA_INIT //前面說(shuō)過(guò)是空白的1 // 引用計(jì)數(shù)為1type: PyType_Type 指向自己} PyObject結(jié)構(gòu)體部分size:0 //變長(zhǎng)對(duì)象,默認(rèn)長(zhǎng)度給了0 }PyVarObject結(jié)構(gòu)體部分總結(jié)
有些是自己的理解,可有錯(cuò)誤,歡迎大佬們指正~
總結(jié)
以上是生活随笔為你收集整理的python3.7源码剖析——python对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java web应用程序_如何构建Jav
- 下一篇: python自定义事件event的含义_