Python 是一種面向對象的編程語言,其核心思想是“萬物皆對象”。這意味著在 Python 中,所有的數據類型、函數、模塊、類等都是對象。本文將通過分析 Python 的源碼,深入探討“萬物皆對象”這一概念的具體實現。
在 Python 中,所有的對象都是 PyObject 類型的實例。PyObject 是 Python 對象模型的基礎,定義在 Include/object.h 文件中:
typedef struct _object {
PyObject_HEAD
} PyObject;
PyObject_HEAD 是一個宏,定義了每個對象都必須包含的頭部信息:
#define PyObject_HEAD \
_PyObject_HEAD_EXTRA \
Py_ssize_t ob_refcnt; \
struct _typeobject *ob_type;
ob_refcnt:引用計數,用于管理對象的內存。ob_type:指向對象的類型對象,類型對象本身也是一個 PyObject。類型對象是描述對象類型的對象,定義在 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;
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;
/* More standard operations (here for binary compatibility) */
hashfunc tp_hash;
ternaryfunc tp_call;
reprfunc tp_str;
getattrofunc tp_getattro;
setattrofunc tp_setattro;
/* Functions to access object as input/output buffer */
PyBufferProcs *tp_as_buffer;
/* Flags to define presence of optional/expanded features */
unsigned long tp_flags;
const char *tp_doc; /* Documentation string */
/* Assigned meaning in release 2.0 */
/* call function for all accessible objects */
traverseproc tp_traverse;
/* delete references to contained objects */
inquiry tp_clear;
/* Assigned meaning in release 2.1 */
/* rich comparisons */
richcmpfunc tp_richcompare;
/* weak reference enabler */
Py_ssize_t tp_weaklistoffset;
/* Iterators */
getiterfunc tp_iter;
iternextfunc tp_iternext;
/* Attribute descriptor and subclassing stuff */
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
Py_ssize_t tp_dictoffset;
initproc tp_init;
allocfunc tp_alloc;
newfunc tp_new;
freefunc tp_free; /* Low-level free-memory routine */
inquiry tp_is_gc; /* For PyObject_IS_GC */
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
PyObject *tp_cache;
PyObject *tp_subclasses;
PyObject *tp_weaklist;
destructor tp_del;
/* Type attribute cache version tag. Added in version 2.6 */
unsigned int tp_version_tag;
destructor tp_finalize;
} PyTypeObject;
類型對象包含了對象的各種操作方法和屬性,例如對象的創建、銷毀、比較、哈希等。
在 Python 中,對象的創建通常通過調用類型對象的 tp_new 和 tp_init 方法來完成。例如,創建一個整數對象:
a = 42
在底層,Python 會調用 PyLong_FromLong 函數來創建一個整數對象:
PyObject *PyLong_FromLong(long ival) {
PyLongObject *v;
/* ... */
v = _PyLong_New(1);
if (v != NULL) {
v->ob_digit[0] = (digit)abs(ival);
/* ... */
}
return (PyObject *)v;
}
對象的銷毀通過引用計數機制來管理。當對象的引用計數降為 0 時,Python 會自動調用對象的 tp_dealloc 方法來釋放對象的內存。例如,整數對象的 tp_dealloc 方法定義如下:
static void int_dealloc(PyObject *v) {
Py_TYPE(v)->tp_free(v);
}
Python 使用引用計數來管理對象的內存。每個對象都有一個 ob_refcnt 字段,用于記錄當前有多少個引用指向該對象。當引用計數降為 0 時,對象會被銷毀。
引用計數的操作通過 Py_INCREF 和 Py_DECREF 宏來實現:
#define Py_INCREF(op) ( \
_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \
((PyObject *)(op))->ob_refcnt++)
#define Py_DECREF(op) \
do { \
if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \
--((PyObject *)(op))->ob_refcnt != 0) \
_Py_CHECK_REFCNT(op) \
else \
_Py_Dealloc((PyObject *)(op)); \
} while (0)
在 Python 中,類型對象本身也是對象,因此類型對象也有自己的類型。所有類型對象的類型都是 PyType_Type,定義在 Objects/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 */
/* ... */
};
類型對象之間可以通過繼承關系形成類型層次結構。例如,整數類型 PyLong_Type 繼承自 PyType_Type:
PyTypeObject PyLong_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int", /* tp_name */
sizeof(PyLongObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)int_dealloc, /* tp_dealloc */
/* ... */
};
通過分析 Python 的源碼,我們可以看到“萬物皆對象”這一概念在 Python 中的具體實現。所有的對象都是 PyObject 類型的實例,類型對象本身也是對象,并且通過引用計數機制來管理對象的內存。理解這些底層機制有助于我們更好地掌握 Python 的面向對象編程思想。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。