• 读python源码--对象模型


      学python的人都知道,python中一切皆是对象,如class生成的对象是对象,class本身也是对象,int是对象,str是对象,dict是对象...。所以,我很好奇,python是怎样实现这些对象的?带着这份好奇,我决定去看看python的源码,毕竟源码才是满足自己好奇心最直接的方法。

      在object.h文件中,定义了两种数据结构PyObject和PyVarObject,代码如下:

     1 #define PyObject_HEAD                
     2     Py_ssize_t ob_refcnt;               
     3     struct _typeobject *ob_type;
     4 
     5 #define PyObject_VAR_HEAD       
     6     PyObject_HEAD                       
     7     Py_ssize_t ob_size;
     8 
     9 typedef struct _object {
    10     PyObject_HEAD
    11 } PyObject;
    12 
    13 typedef struct {
    14     PyObject_VAR_HEAD
    15 } PyVarObject;

      这两种数据结构分别对应python的两种对象:固定长度对象和可变长度对象。python中的所有对象都属于这两种对象中的一种,如int,float是固定长度对象,list,str,dict是可变长度对象。从上面两种对象数据结构定义来看,可变长度对象和固定长度对象的头都是PyObject结构体,也就是说python中所有对象的开头都包含这个结构体,并且可以用PyObject *指针来访问任何对象,这种访问对象的方法在python的源码中随处可见。PyObject结构体包含两个成员,ob_refcnt和ob_type指针。ob_refcnt用来表示对象被引用的次数,当ob_refcnt == 0时,这个对象会被立即销毁;ob_type指针指向了一个_typeobject类型的结构体,表示对象所属的类型,也就是生成该对象的类型,这其实很类似于面向对象中类与实例的关系,PyObject是某个类的实例,ob_type表示这个类。但与面向对象不同的是,ob_type本身也是个对象,我们来看下_typeobject的定义:

     1 typedef struct _typeobject {
     2     PyObject_VAR_HEAD
     3     const char *tp_name; /*类型名 */
     4     Py_ssize_t tp_basicsize, tp_itemsize; /* 实例化对象的大小 */
     5 
     6     /* 标准方法 */
     7 
     8     destructor tp_dealloc;
     9     printfunc tp_print;
    10     getattrfunc tp_getattr;
    11     setattrfunc tp_setattr;
    12     cmpfunc tp_compare;
    13     reprfunc tp_repr;
    14 
    15     /* 标准类(数值类,列表类,dict类)方法*/
    16 
    17     PyNumberMethods *tp_as_number;
    18     PySequenceMethods *tp_as_sequence;
    19     PyMappingMethods *tp_as_mapping;
    20 
    21     /* 其它标准方法*/
    22 
    23     hashfunc tp_hash;
    24     ternaryfunc tp_call;
    25     reprfunc tp_str;
    26     getattrofunc tp_getattro;
    27     setattrofunc tp_setattro;
    28     ...   
    29 } PyTypeObject;

      从上面定义来看,_typeobject的开头也包含了PyObject结构体,所以它也是一个对象,既然它也是一个对象,那么按照面向对象的理解,它又是谁来生成的呢?答案是所有PyTypeObject对象都是通过PyType_Type来生成的,包括PyType_Type本身,因为PyType_Type也是PyTypeObject对象,有点绕。PyType_Type的定义是通过将PyType_Type声明为全局静态变量实现的,具体如下:

     1 PyTypeObject PyType_Type = {
     2     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     3     "type",                                     /* tp_name */
     4     sizeof(PyHeapTypeObject),                   /* tp_basicsize */
     5     sizeof(PyMemberDef),                        /* tp_itemsize */
     6     (destructor)type_dealloc,                   /* tp_dealloc */
     7     0,                                          /* tp_print */
     8     0,                                          /* tp_getattr */
     9     0,                                          /* tp_setattr */
    10     0,                                  /* tp_compare */
    11     (reprfunc)type_repr,                        /* tp_repr */
    12     0,                                          /* tp_as_number */
    13     0,                                          /* tp_as_sequence */
    14     0,                                          /* tp_as_mapping */
    15     (hashfunc)_Py_HashPointer,                  /* tp_hash */
    16     (ternaryfunc)type_call,                     /* tp_call */
    17     0,                                          /* tp_str */
    18     (getattrofunc)type_getattro,                /* tp_getattro */
    19     (setattrofunc)type_setattro,                /* tp_setattro */
    20     0,                                          /* tp_as_buffer */
    21     ...
    22 }

      从PyType_Type定义来看,ob_type被初始化为它自己的地址,所以PyType_Type的类型就是自己。从python源码实现来看,所有PyTypeObject的ob_type都会指向PyType_Type对象,所以PyType_Type是所有类型的类型,称之为元类。python中定义了很多内建的类型对象,如PyInt_Type (int类型),PyStr_Type (str类型),PyDict_Type(dict类型) 类型对象,下面看下PyInt_Type类型的定义:

     1 PyTypeObject PyInt_Type = {
     2     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     3     "int",
     4     sizeof(PyIntObject),
     5     0,
     6     (destructor)int_dealloc,                    /* tp_dealloc */
     7     (printfunc)int_print,                       /* tp_print */
     8     0,                                          /* tp_getattr */
     9     0,                                          /* tp_setattr */
    10     (cmpfunc)int_compare,                       /* tp_compare */
    11     (reprfunc)int_to_decimal_string,            /* tp_repr */
    12     &int_as_number,                             /* tp_as_number */
    13     0,                                          /* tp_as_sequence */
    14     0,                                          /* tp_as_mapping */
    15     (hashfunc)int_hash,                         /* tp_hash */
    16     0,                                          /* tp_call */
    17     ...
    18 };

      从PyInt_Type定义来看,它主要包含了int数据类型相关的方法。PyInt_Type 类型对象的初始化和PyType_Type 类型类似,PyInt_Type类型的定义也是通过全局静态变量的方式实现的,除了PyInt_Type了下,所有python内建类型都是以这种方式定义的。这些类型产生的对象都会共享这些类型对象,包括这些类型定义的方法。

      在python中,怎样查看对象的类型呢?有两种方法,一种是直接type:

    1 >>> x = 1
    2 >>> type(x)
    3 <type 'int'>

      另一种是通过对象的__class__属性:

    1 >>> x = 1
    2 >>> type(x)
    3 <type 'int'>
    4 >>> x.__class__
    5 <type 'int'>

      现在来看看int,str,dict这些类型的类型:

    1 <type 'int'>
    2 >>> type(int)
    3 <type 'type'>
    4 >>> type(str)
    5 <type 'type'>
    6 >>> type(dict)
    7 <type 'type'>
    8 >>> type(type)
    9 <type 'type'>

      从这个输出来看,int,str,dict这些类型的类型都是type,这也印证了前面说的,所有类型都是通过元类type生成的。

  • 相关阅读:
    C语言堆栈入门——堆和栈的区别
    Unity时钟定时器插件——Vision Timer源码分析之一
    UNITY3D 2D物流流体插件下载|Liquid Physics 2D
    Unity3d插件Master Audio AAA Sound v3.5
    游戏行业的女性拥有强大的新盟友:Facebook
    Unity游戏设计与实现 南梦宫一线程序员的开发实例
    Unity4.6证书激活问题
    里诺全系列注册机+暗桩patch
    冰点还原8.53破解版
    NSE: known a priori estimate
  • 原文地址:https://www.cnblogs.com/chengxuyuancc/p/5402020.html
Copyright © 2020-2023  润新知