萬物皆對象,Python的對象概述(簡述)

在 Python 的世界中,一切皆對象。int/list/dict / … 都是對象,除此之外,函數、類本身也是對象,那麼,這些對象究竟是什麼呢?
注 : 要是看不懂, 直接跳轉到最後。

從結果看,Python 中的對象是 C 語言中結構體在堆上申請的一片內存區域。而在具體實現上,這裏先簡單描述一下。

萬物基於 MIUI: PyObject

在 Python 中,所有對象都共有一些特性,這些特性定義在PyObject 中。PyObject定義在Include/object.h中:

#define PyObject_HEAD                   \
    _PyObject_HEAD_EXTRA                \
    Py_ssize_t ob_refcnt;               \
    struct _typeobject *ob_type;

typedef struct _object {
    PyObject_HEAD
} PyObject;

簡化後即爲:

typedef struct _object {
    int ob_refcnt;               
    struct _typeobject *ob_type;
} PyObject;

PyObject 中,ob_refcnt 用以記錄對象的引用數(與引用計數的內存回收相關,這裏暫且不表),當有新的指針指向某對象時,ob_refcnt 的值加 1, 當指向某對象的指針刪除時,ob_refcnt 的值減 1,當其值爲零的時候,則可以將該對象從堆中刪除(事實上並不會立即刪除,這裏暫且不表)。除了 ob_refcnt 之外,還有一個 指向 _typeobject指針 ob_type。這個結構體用於表示對象類型。跳過 _typeobject,可以發現, Python 對象的核心在於一個引用計數和一個類型信息。

PyObject 定義的內容會出現在每個對象所佔內存的開始部分。

定長對象與變長對象

在 Python 中,除了 bool float這樣的定長對象(一旦確定下來需要的內存,便不再有改動),還有另外一種對象:長度可變的對象。這種對象在 Python 的實現中通過PyVarObject結構體來表示:

#define PyObject_VAR_HEAD               \
    PyObject_HEAD                       \
    Py_ssize_t ob_size; /* Number of items in variable part */

typedef struct {
    PyObject_VAR_HEAD
} PyVarObject;

由此,Python 中所有對象在實現的時候,內存無非如下兩種情況:

   定長對象              變長對象
+-----------+       +-----------+
| ob_refcnt |       | ob_refcnt |
+-----------+       +-----------+
|  ob_type  |       |  ob_type  |
+-----------+       +-----------+
|           |       |  ob_size  |
|           |       +-----------+
|   other   |       |           |
|           |       |   other   |
|           |       |           |
+-----------+       +-----------+

道生一:PyTypeObject

在描述 PyObject的時候,提到了一個 _typeobject結構體。那麼,它是幹什麼的呢?想象一下,一個對象在創建的時候需要多少內存、這個對象的類名是什麼等等信息,又是如何記錄和區分的呢?

_typeobject(也就是PyTypeObject)可以被稱之爲“指定對象類型的類型對象”,其定義如下:

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 */

    // ...... 省略部分暫時不關心的內容

} PyTypeObject;

可以理解爲,PyTypeObject 對象是 Python 中面向對象理念中“類”這個概念的實現,這裏只是簡單介紹其定義中的部分內容:

  • ty_name:類型名
  • tp_basicsize, tp_itemsize:創建類型對象時分配的內存大小信息
  • 被省略掉的部分:與該類型關聯的操作(函數指針)
    這裏只是簡單描述,上面的內容有些偏頗,暫不必過分深究。

再看一眼 PyTypeObject的定義,可以發現在最開始也有一個 PyObject_VAR_HEAD,這意味着它也是一個對象。那麼,PyTypeObject 既然是指示類型的對象,那麼它的類型又是什麼呢?答案是PyType_Type

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 */
    // ...... 省略了部分內容
};

事實上,它就是 Python 語言中的type 對象就是 PyType_Type,它是所有classclass,在 Python 中叫做 metaclass。其實,在實現中它的 ob_type 指針又指向了自己本身,既是:

   PyType_Type
+-----------+<-------+
| ob_refcnt |        |
+-----------+        |
|  ob_size  +--------+
+-----------+
|           |
|   other   |
|           |
+-----------+

小結

簡單概述了 Python 中的對象的最模糊的概念。

要是看不懂的小夥伴。 可以加我的學習交流羣: 725479218。 直播、交流、書籍、練習題(羣文件)。都有
看得懂的小夥伴可以在後方評論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章