最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python源碼學(xué)習(xí)之PyObject和PyTypeObject

 更新時(shí)間:2021年06月16日 09:56:41   作者:Jakob_Hu  
今天給大家?guī)淼氖顷P(guān)于Python源碼的相關(guān)知識(shí)學(xué)習(xí),文章圍繞著PyObject和PyTypeObject展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下

前言

Python是C語言實(shí)現(xiàn)的,因此Python對(duì)象在C語言層面應(yīng)該是一個(gè)結(jié)構(gòu)體 ,組織對(duì)象占用的內(nèi)存。 不同類型的對(duì)象,數(shù)據(jù)及行為均可能不同,因此可以大膽猜測:不同類型的對(duì)象由不同的結(jié)構(gòu)體表示。

對(duì)象也有一些共性,比如每個(gè)對(duì)象都需要有一個(gè)引用計(jì)數(shù),用于實(shí)現(xiàn)垃圾回收機(jī)制。因此,還可以進(jìn)一步猜測:表示對(duì)象的結(jié)構(gòu)體有一個(gè)公共頭部。

一. 實(shí)例對(duì)象的基石—PyObject和PyVarObject

PyObject和PyVarObject本質(zhì)上是對(duì)象的頭部信息。

1.1 PyObject結(jié)構(gòu)體

Python對(duì)象都由PyObject結(jié)構(gòu)體表示,對(duì)象引用則是指針PyObject *PyObject結(jié)構(gòu)體定義于頭文件object.h,路徑為Include/object.h,代碼如下

typedef struct _object {
    _PyObject_HEAD_EXTRA
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;

對(duì)結(jié)構(gòu)體中的元素進(jìn)行說明,

元素名稱 說明
ob_refcnt 引用計(jì)數(shù),對(duì)象被其他地方引用時(shí)加一,引用解除時(shí)減一; 當(dāng)引用計(jì)數(shù)為零,便可將對(duì)象回收,這是最簡單的垃圾回收機(jī)制。
ob_type 類型指針指向?qū)ο蟮念愋蛯?duì)象,類型對(duì)象描述實(shí)例對(duì)象的數(shù)據(jù)及行為。
_PyObject_HEAD_EXTRA 宏,同樣定義在Include/object.h頭文件內(nèi)。

1.2 宏的定義

#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

如果Py_TRACE_REFS被定義,宏展開為兩個(gè)指針ob_nextob_prev用來實(shí)現(xiàn)雙向鏈表。注釋中說明,雙向鏈表用于跟蹤所有活躍堆對(duì)象,一般不啟用,不深入介紹。

1.3 PyVarObject結(jié)構(gòu)體

用于表示變長對(duì)象PyVarObject結(jié)構(gòu)體是在PyObject結(jié)構(gòu)體的基礎(chǔ)上加入長度信息。

typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;

相比object結(jié)構(gòu)體增加了ob_size字段用于記錄元素個(gè)數(shù)。

Alt

1.4 兩種頭部信息宏定義及其初始化

具體實(shí)例對(duì)象視其內(nèi)存大小是否固定,決定其屬于定長對(duì)象還是變長對(duì)象。相應(yīng)的需要具有頭部信息PyObjectPyVarObject。

因此,頭文件準(zhǔn)備了兩個(gè)頭部信息的宏定義PyObject_HEADPyObject_VAR_HEAD,方便對(duì)象使用,

#define PyObject_HEAD          PyObject ob_base;
#define PyObject_VAR_HEAD      PyVarObject ob_base;

宏定義說明,

#define PyObject_HEAD PyObject ob_base;
表示將代碼中其他出現(xiàn)PyObject_HEAD的地方,替換成PyObject ob_base;

1.4.1 定長對(duì)象實(shí)現(xiàn)

內(nèi)存大小固定的浮點(diǎn)數(shù)類的實(shí)現(xiàn)只需在PyObject頭部基礎(chǔ)上,用一個(gè)雙精度浮點(diǎn)數(shù)double加以實(shí)現(xiàn),

typedef struct {
    PyObject_HEAD

    double ob_fval;
} PyFloatObject;

Alt

1.4.2 變長對(duì)象實(shí)現(xiàn)

內(nèi)存大小不固定的列表對(duì)象則需要在PyVarObject頭部的基礎(chǔ)上,用一個(gè)動(dòng)態(tài)數(shù)組加以實(shí)現(xiàn),數(shù)組存儲(chǔ)列表包含的對(duì)象,即 PyObject 指針,

typedef struct {
    PyObject_VAR_HEAD

    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

Alt

PyListObject底層由一個(gè)數(shù)組實(shí)現(xiàn),關(guān)鍵字段是以下3個(gè),

字段 說明
ob_item 指向動(dòng)態(tài)數(shù)組的指針,數(shù)組保存元素對(duì)象指針。
allocated 動(dòng)態(tài)數(shù)組總長度,即列表當(dāng)前的 容量。
ob_size 當(dāng)前元素個(gè)數(shù),即列表當(dāng)前的 長度。

列表容量不足時(shí),Python會(huì)自動(dòng)擴(kuò)容,具體機(jī)制見list源碼解讀。

1.4.3 頭部信息宏初始化

PyObject_HEAD_INIT用于定長對(duì)象頭部信息初始化。將引用計(jì)數(shù)ob_refcnt設(shè)置為1并將對(duì)象類型ob_type設(shè)置成給定類型。

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

PyVarObject_HEAD_INIT用于變長對(duì)象頭部信息初始化。在前者基礎(chǔ)上進(jìn)一步設(shè)置長度字段ob_size。

#define PyVarObject_HEAD_INIT(type, size)       \
    { PyObject_HEAD_INIT(type) size },

在源碼中經(jīng)常見到這兩個(gè)宏定義。

二. 類型對(duì)象的基石—PyTypeObject 2.1 PyTypeObject包含信息

PyObject記錄了Python中所有對(duì)象共有的信息。如引用計(jì)數(shù)、類型指針和變長對(duì)象特有的元素個(gè)數(shù)。但是還有一些細(xì)節(jié)需要考慮,

  • 創(chuàng)建不同類型的對(duì)象時(shí)如何得知對(duì)象所需的內(nèi)存信息
  • 給定某個(gè)對(duì)象,如何判斷它支持什么操作

這些作為對(duì)象的元信息 ,應(yīng)該由一個(gè)獨(dú)立實(shí)體保存,與對(duì)象所屬類型密切相關(guān)。PyObject中包含的ob_type指針,指向一個(gè)類型對(duì)象。類型對(duì)象PyTypeObject也在Include/object.h中定義,關(guān)鍵字段如下,

typedef struct _typeobject {
    PyObject_VAR_HEAD
    const 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;

    // ...
    /* Attribute descriptor and subclassing stuff */
    struct _typeobject *tp_base;

    // ......
} PyTypeObject;

類型對(duì)象PyTypeObject是一個(gè)變長對(duì)象,包含變長對(duì)象頭部信息PyObject_VAR_HEAD和專有字段,

字段 說明
類型名稱 tp_name字段
類型的繼承信息 tp_base字段指向基類對(duì)象
創(chuàng)建實(shí)例對(duì)象時(shí)所需的內(nèi)存信息 tp_basicsize 和 tp_itemsize 字段
該類型支持的相關(guān)操作信息 tp_print、tp_getattr等函數(shù)指針

PyTypeObject就是類型對(duì)象在 Python 中的表現(xiàn)形式,對(duì)應(yīng)著面向?qū)ο笾小邦悺钡母拍睢?code>PyTypeObject結(jié)構(gòu)很復(fù)雜,目前只需要知道它保存著對(duì)象的元信息,描述對(duì)象的類型即可。

2.2 類型對(duì)象和實(shí)例對(duì)象在內(nèi)存中的關(guān)系

以float為例,考察類型對(duì)象和實(shí)例對(duì)象在內(nèi)存中的形態(tài)和關(guān)系,

>>> float
<class 'float'>
>>> pi = 3.14
>>> e = 2.71
>>> type(pi) is float
True

Alt

  • 兩個(gè)float實(shí)例對(duì)象都是PyFloatObject結(jié)構(gòu)體,除了公共頭部字段ob_refcntob_type,專有字段ob_fval保存了對(duì)應(yīng)的數(shù)值。
  • 類型對(duì)象是一個(gè)PyTypeObject結(jié)構(gòu)體,保存了類型名、內(nèi)存分配信息以及浮點(diǎn)數(shù)相關(guān)操作。實(shí)例對(duì)象的ob_type字段指向類型對(duì)象,Python 據(jù)此判斷對(duì)象類型,進(jìn)而獲悉關(guān)于對(duì)象的元信息。
  • float、pi以及e等變量只是一個(gè)指向?qū)嶋H對(duì)象的指針。

上圖的內(nèi)容并不完全正確,更深入的解讀見后一篇博文。

到此這篇關(guān)于Python源碼學(xué)習(xí)之PyObject和PyTypeObject的文章就介紹到這了,更多相關(guān)PyObject和PyTypeObject內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • keras 多任務(wù)多l(xiāng)oss實(shí)例

    keras 多任務(wù)多l(xiāng)oss實(shí)例

    這篇文章主要介紹了keras 多任務(wù)多l(xiāng)oss實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • python自動(dòng)格式化json文件的方法

    python自動(dòng)格式化json文件的方法

    這篇文章主要介紹了python自動(dòng)格式化json文件的方法,可實(shí)現(xiàn)將json文件格式化的功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-03-03
  • python讀取json文件并將數(shù)據(jù)插入到mongodb的方法

    python讀取json文件并將數(shù)據(jù)插入到mongodb的方法

    這篇文章主要介紹了python讀取json文件并將數(shù)據(jù)插入到mongodb的方法,實(shí)例分析了Python操作json及mongodb數(shù)據(jù)庫的技巧,需要的朋友可以參考下
    2015-03-03
  • Python中.py文件和.ipynb文件的區(qū)別詳解

    Python中.py文件和.ipynb文件的區(qū)別詳解

    Python開發(fā)者常用的兩種文件格式.py和.ipynb各有特點(diǎn),本教程將通過對(duì)比分析、代碼示例和場景說明,幫助開發(fā)者全面理解二者的區(qū)別與聯(lián)系,需要的朋友可以參考下
    2025-04-04
  • 使用grappelli為django admin后臺(tái)添加模板

    使用grappelli為django admin后臺(tái)添加模板

    本文介紹了一款非常流行的Django模板系統(tǒng)--grappelli,以及如何給Django的admin后臺(tái)添加模板,非常的實(shí)用,這里推薦給大家。
    2014-11-11
  • 解決pycharm導(dǎo)入numpy包的和使用時(shí)報(bào)錯(cuò):RuntimeError: The current Numpy installation (‘D:\\python3.6\\lib\\site-packa的問題

    解決pycharm導(dǎo)入numpy包的和使用時(shí)報(bào)錯(cuò):RuntimeError: The current Numpy ins

    這篇文章主要介紹了解決pycharm導(dǎo)入numpy包的和使用時(shí)報(bào)錯(cuò):RuntimeError: The current Numpy installation (‘D:\\python3.6\\lib\\site-packa的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 詳解Pandas的三大利器(map,apply,applymap)

    詳解Pandas的三大利器(map,apply,applymap)

    這篇文章主要為大家介紹了pandas中的三大利器: map、apply、applymap,他們經(jīng)常在進(jìn)行數(shù)據(jù)處理的時(shí)候用到,需要的可以參考一下
    2022-02-02
  • Python3 安裝PyQt5及exe打包圖文教程

    Python3 安裝PyQt5及exe打包圖文教程

    今天小編就為大家分享一篇Python3 安裝PyQt5及exe打包圖文教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python利用pandas處理CSV文件的用法示例

    Python利用pandas處理CSV文件的用法示例

    pandas是一個(gè)第三方數(shù)據(jù)分析庫,其集成了大量的數(shù)據(jù)分析工具,可以方便的處理和分析各類數(shù)據(jù),本文將給大家介紹Python利用pandas處理CSV文件的用法示例,文中通過代碼和圖文講解的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • numpy中的log和ln函數(shù)解讀

    numpy中的log和ln函數(shù)解讀

    這篇文章主要介紹了numpy中的log和ln函數(shù)解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評(píng)論

祁门县| 保山市| 贞丰县| 巴中市| 开原市| 河北区| 屏南县| 滦平县| 蒙自县| 天柱县| 襄樊市| 惠安县| 河南省| 青岛市| 高青县| 蓝田县| 柳林县| 永登县| 绥阳县| 呼玛县| 广德县| 大厂| 绥中县| 云浮市| 水城县| 谢通门县| 内江市| 临颍县| 鄂托克前旗| 泸溪县| 峡江县| 东阳市| 镇安县| 普格县| 津市市| 浪卡子县| 财经| 珲春市| 玛纳斯县| 绥江县| 广州市|