好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > Python源碼學習之PyObject和PyTypeObject

Python源碼學習之PyObject和PyTypeObject

熱門標簽:洪澤縣地圖標注 北京電信外呼系統靠譜嗎 無錫客服外呼系統一般多少錢 大連crm外呼系統 百度地圖標注位置怎么修改 高德地圖標注是免費的嗎 地圖標注視頻廣告 梅州外呼業務系統 老人電話機器人

前言

Python是C語言實現的,因此Python對象在C語言層面應該是一個結構體 ,組織對象占用的內存。 不同類型的對象,數據及行為均可能不同,因此可以大膽猜測:不同類型的對象由不同的結構體表示

對象也有一些共性,比如每個對象都需要有一個引用計數,用于實現垃圾回收機制。因此,還可以進一步猜測:表示對象的結構體有一個公共頭部

一. 實例對象的基石—PyObject和PyVarObject

PyObject和PyVarObject本質上是對象的頭部信息

1.1 PyObject結構體

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

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

對結構體中的元素進行說明,

元素名稱 說明
ob_refcnt 引用計數,對象被其他地方引用時加一,引用解除時減一; 當引用計數為零,便可將對象回收,這是最簡單的垃圾回收機制。
ob_type 類型指針指向對象的類型對象,類型對象描述實例對象的數據及行為。
_PyObject_HEAD_EXTRA 宏,同樣定義在Include/object.h頭文件內。

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被定義,宏展開為兩個指針ob_nextob_prev用來實現雙向鏈表。注釋中說明,雙向鏈表用于跟蹤所有活躍堆對象,一般不啟用,不深入介紹。

1.3 PyVarObject結構體

用于表示變長對象PyVarObject結構體是在PyObject結構體的基礎上加入長度信息。

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

相比object結構體增加了ob_size字段用于記錄元素個數。

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

具體實例對象視其內存大小是否固定,決定其屬于定長對象還是變長對象。相應的需要具有頭部信息PyObjectPyVarObject

因此,頭文件準備了兩個頭部信息的宏定義PyObject_HEADPyObject_VAR_HEAD,方便對象使用,

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

宏定義說明,

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

1.4.1 定長對象實現

內存大小固定的浮點數類的實現只需在PyObject頭部基礎上,用一個雙精度浮點數double加以實現,

typedef struct {
    PyObject_HEAD

    double ob_fval;
} PyFloatObject;

1.4.2 變長對象實現

內存大小不固定的列表對象則需要在PyVarObject頭部的基礎上,用一個動態數組加以實現,數組存儲列表包含的對象,即 PyObject 指針,

typedef struct {
    PyObject_VAR_HEAD

    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

PyListObject底層由一個數組實現,關鍵字段是以下3個,

字段 說明
ob_item 指向動態數組的指針,數組保存元素對象指針。
allocated 動態數組總長度,即列表當前的 容量。
ob_size 當前元素個數,即列表當前的 長度。

列表容量不足時,Python會自動擴容,具體機制見list源碼解讀。

1.4.3 頭部信息宏初始化

PyObject_HEAD_INIT用于定長對象頭部信息初始化。將引用計數ob_refcnt設置為1并將對象類型ob_type設置成給定類型。

#define PyObject_HEAD_INIT(type)        \

    { _PyObject_EXTRA_INIT              \

    1, type },

PyVarObject_HEAD_INIT用于變長對象頭部信息初始化。在前者基礎上進一步設置長度字段ob_size

#define PyVarObject_HEAD_INIT(type, size)       \

    { PyObject_HEAD_INIT(type) size },

在源碼中經常見到這兩個宏定義。

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

PyObject記錄了Python中所有對象共有的信息。如引用計數、類型指針和變長對象特有的元素個數。但是還有一些細節需要考慮,

  • 創建不同類型的對象時如何得知對象所需的內存信息
  • 給定某個對象,如何判斷它支持什么操作

這些作為對象的元信息 ,應該由一個獨立實體保存,與對象所屬類型密切相關。PyObject中包含的ob_type指針,指向一個類型對象。類型對象PyTypeObject也在Include/object.h中定義,關鍵字段如下,

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;

類型對象PyTypeObject是一個變長對象,包含變長對象頭部信息PyObject_VAR_HEAD和專有字段,

字段 說明
類型名稱 tp_name字段
類型的繼承信息 tp_base字段指向基類對象
創建實例對象時所需的內存信息 tp_basicsize 和 tp_itemsize 字段
該類型支持的相關操作信息 tp_print、tp_getattr等函數指針

PyTypeObject就是類型對象在 Python 中的表現形式,對應著面向對象中“類”的概念。PyTypeObject結構很復雜,目前只需要知道它保存著對象的元信息,描述對象的類型即可。

2.2 類型對象和實例對象在內存中的關系

以float為例,考察類型對象和實例對象在內存中的形態和關系,

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

  • 兩個float實例對象都是PyFloatObject結構體,除了公共頭部字段ob_refcntob_type,專有字段ob_fval保存了對應的數值。
  • 類型對象是一個PyTypeObject結構體,保存了類型名、內存分配信息以及浮點數相關操作。實例對象的ob_type字段指向類型對象,Python 據此判斷對象類型,進而獲悉關于對象的元信息。
  • float、pi以及e等變量只是一個指向實際對象的指針。

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

到此這篇關于Python源碼學習之PyObject和PyTypeObject的文章就介紹到這了,更多相關PyObject和PyTypeObject內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python源碼解析之List
  • python源碼剖析之PyObject詳解
  • python opencv人臉識別考勤系統的完整源碼
  • python 制作手機歸屬地查詢工具(附源碼)
  • python基于tkinter制作無損音樂下載工具(附源碼)
  • Python bsonrpc源碼解讀
  • Python源碼學習之PyType_Type和PyBaseObject_Type詳解
  • Python制作腳本幫女朋友搶購清空購物車

標簽:洛陽 怒江 安慶 吉林 岳陽 清遠 泉州 長春

巨人網絡通訊聲明:本文標題《Python源碼學習之PyObject和PyTypeObject》,本文關鍵詞  Python,源碼,學,習之,PyObject,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Python源碼學習之PyObject和PyTypeObject》相關的同類信息!
  • 本頁收集關于Python源碼學習之PyObject和PyTypeObject的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: jul-506人妻秘书汗と接吻| 日韩黄色片网站| 阿娇陈冠希露双奶头被删视频| 啊啊啊好大好爽视频| 日本一级无码爽A片免费丁给片| 欧美无遮挡又硬又粗A片免费视频| 色日本在线| 国产精品吹潮香蕉在线观看| 免费午夜网站| 经典wc偷窥小便6| k8经典成人理伦片| 国产精品偷伦视频免费看2023| 老司机ae86最舒适的赛道| 49pao强力在线高清基地| 伊人精品A片一区二区三区| 97精产国品一二三产区区别小说 | 三级全黄的视频| 综合色在线| 久久精品亚洲精品五月色| 成人网站在线进入爽爽爽| 激情视频在线免费观看| 同桌张开腿让我爽了一夜| 色精阁久艾草国产WWW| 0855午夜福利100集| 欧美XXOO午夜无码区| 制服丝袜中出| 欧美精品免费xxxxx视频| 久青草国产在线视频亚瑟影视| 久久电影精品久久99久久| 久久久亚洲综合久久久久久 | 近親相姦中文字幕| 女上男下高潮太舒服了| 国产沙发午睡在线观看系列 | 囯产精品久久久久久久久久大尺度| 韩国理论片在线观看| 最新众筹乔依琳38分30秒| 两女舌吻互揉下身| 亚欧成人一区二区| 国产TS系列超美的妖妖时诗君君| japanese50mature伦| 别揉我胸啊嗯上课呢的作文 |