Python源碼 -- C語言實現面向對象編程(基類&派生類&多態)

背景

python是面向對象的解釋性語言,然而python是通過C語言實現的,C語言怎麼跟面向對象扯上了關係? C語言可以實現面向對象的性質? 

原文鏈接:http://blog.csdn.net/ordeder/article/details/25296307

【基礎數據結構】

#define PyObject_HEAD                   \
    _PyObject_HEAD_EXTRA                \
    Py_ssize_t ob_refcnt;               \
    struct _typeobject *ob_type;
以上宏等價於:

  Py_ssize_t ob_refcnt;
  struct _typeobject *ob_type;
參數: ob_refcnt 作爲引用計數(類似智能指針的概念),當引用計數爲0的時候對象及被銷燬。

參數:_typeobject 即 PyTypeObject實現如下:在python中,一切對對象,包括類型也是一種對象。

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;
    cmpfunc tp_compare;
    reprfunc tp_repr;

    /* Method suites for standard classes */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

  ...
    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;

...
} PyTypeObject;

【Python中對象的基類--C語言實現類的概念及其繼承】

typedef struct _object {
    PyObject_HEAD
} PyObject;

整數類:
主要用一個long類型存儲整數的值。

typedef struct {  
    PyObject_HEAD   
    long ob_ival;  
} PyIntObject; 

還比如python中的其他複雜類型的類PyDictObject:

typedef struct _dictobject PyDictObject;
struct _dictobject {
    PyObject_HEAD
    Py_ssize_t ma_fill;  /* # Active + # Dummy */
    ...
    PyDictEntry *ma_table;
    ...
};
通過對比PyIntObject和PyDictObject可得:類PyIntObject和PyDictObject都繼承了基類PyObject(PyObject_HEAD)。


【PyObject & PyTypeObject -- C語言實現多態】

PyIntObject和PyDictObject對PyObject_HEAD中的ob_type的賦值是不同的,分別爲:

PyTypeObject PyInt_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "int",
    sizeof(PyIntObject),
    0,
    (destructor)int_dealloc,                    /* tp_dealloc */
    (printfunc)int_print,                       /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    (cmpfunc)int_compare,                       /* tp_compare */
   ...
    int_new,                                    /* tp_new */
    (freefunc)int_free,                         /* tp_free */
};

PyTypeObject PyDict_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "dict",
    sizeof(PyDictObject),
    0,
    (destructor)dict_dealloc,                   /* tp_dealloc */
    (printfunc)dict_print,                      /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    (cmpfunc)dict_compare,                      /* tp_compare */
    ...
    dict_new,                                   /* tp_new */
    PyObject_GC_Del,                            /* tp_free */
};

PyObject 作爲python的基類,PyObject* 指針能夠指向派生類,而派生類中各個類對象對成員ob_type都有自己的解釋(PyIntObject:PyInt_Type PyDictObject:PyDict_Type)
即,ob_type依據類的類型構建了基本操作的回調函數,從而,基類指針指向派生類對象後調用的通用接口,如print函數,將被解釋爲具體派生類的print函數,例如;
PyObject *ppy = &pyintobj;
ppy -> ob_type -> tp_print     即爲: pyintobj -> ob_type -> int_print


PyObject *ppy = &pydictobj;
ppy -> ob_type -> tp_print     即爲: pyintobj -> ob_type -> dict_print

總結:多態,通過不同類對ob_type進行初始化,爲通用函數接口註冊相應的回調函數,即可實現了多態;

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