在 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
,它是所有class
的 class
,在 Python 中叫做 metaclass
。其實,在實現中它的 ob_type
指針又指向了自己本身,既是:
PyType_Type
+-----------+<-------+
| ob_refcnt | |
+-----------+ |
| ob_size +--------+
+-----------+
| |
| other |
| |
+-----------+
小結
簡單概述了 Python 中的對象的最模糊的概念。
要是看不懂的小夥伴。 可以加我的學習交流羣: 725479218。 直播、交流、書籍、練習題(羣文件)。都有
看得懂的小夥伴可以在後方評論。