• 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进行初始化,为通用函数接口注冊对应的回调函数,就可以实现了多态;

  • 相关阅读:
    ubuntu18.04LTS服务器用vituralenv安装和配置pytorch和tensorflow
    ubuntu18.04安装Anaconda
    XeLaTeX下如何以原大小显示PNG
    JS黑魔法之this, setTimeout/setInterval, arguments
    sicily 1198. Substring (递归全排列+排序)
    sicily 1046. Plane Spotting(排序求topN)
    sicily 1051. Biker's Trip Odomete
    sicily 1176. Two Ends (Top-down 动态规划+记忆化搜索 v.s. Bottom-up 动态规划)
    sicily 1035. DNA matching
    关于组织自定义皮肤/主题的一点思考
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6694256.html
Copyright © 2020-2023  润新知