日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python3.7源码剖析——python对象

發(fā)布時(shí)間:2023/12/10 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python3.7源码剖析——python对象 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

學(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 是空白

[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 ob_base; PyObject ob_base;

那么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)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。