python基础

Python中一切都是对象,一个实例是一个对象,生成实例的类也是对象,描述类的元类也是对象。
TODO:类的继承链的图片
这张图里面,可以看出来,无论是内置类型int还是自定义类型dog,他们的基类都是object。而且描述他们类型的元类型都是type,object是所有类型的基类,本质上也是一个类,所以他的类型也是type。Type是所有类型的类型,本质上也是一种类型,所以它继承自object,类型是它自己。总体来看,所有类型的基类都收敛于object,所有类型的类型都是type。

PyObject

Python中的变量只是一个跟对象关联的名字,保存的其实是指向实际对象的指针,变量的赋值操作也就是一个拷贝指针的操作。
Python中对象可以分为可变对象和不可变对象;顾名思义,区别就是创建后对象的值能不能修改。也可分为定长对象和变长对象:区别就是对象大小能不能改变

typedef struct _object {_PyObject_HEAD_EXTRAPy_ssie_t ob_refcnt;    //引用计数PyTypeObject *ob_type; //类型指针
} PyObject;

PyObject结构体是所有对象共用的部分,这其中包含一个引用计数,记录被引用次数,一个类型指针,指向对象的类型对象,比如刚才的dog实例的类型对象,就是dog类。这是一个最基础的对象结构。

PyVarObject

下面这个是变长对象,跟PyObject相比,多出一个ob_size字段,用来记录元素个数。变长比如string,list。

typedef struct {PyObject ob_base;Py_ssize_t ob_size;
} PyVarObject;

PyTypeObject

typedef struct _typeobject {PyObject_VAR_HEADconst char *tp_name;    //类型名称Py_ssize_t tp_basicsize, tp_itemsize; //创建对象所需的内存信息// 该类型支持的操作信息destructor tp_dealloc;printfunc tp_print;getattrfunc tp_getattr;setattrfunc tp_setattr;//...struct _typeobject *tp_base;  //类型的继承信息//...
} PyTypeObject;

在创建对象的时候,不同的对象它肯定需要不同的内存大小,PyObject只提供了所有对象共有的信息,其他的一些元信息,都放在PyTypeObject这个结构体中,也就是前面说的类型对象,它来描述这个对象是什么类型,有什么继承关系,支持什么操作,需要多少内存这些信息。

Object 和 Type_Type

刚才我们还介绍了两个概念,一个是所有类的基类Object,还有一个是描述类型的类型,被称为元类型type。

PyTypeObject PyType_Type = {PyVarObject_HEAD_INIT(&PyType_Type, 0)"type",sizeof(PyHeapTypeObject),sizeof(PyMemberDef),(destructor)type_dealloc,//...(reprfunc)type_repr,(ternaryfunc)type_call,//...
};
PyTypeObject PyBaseObject_Type = {PyVarObject_HEAD_INIT(&PyType_Type, 0)"object",sizeof(PyObject),0,object_dealloc,//...object_repr,
};

Object背后的实体就是PyBaseObject_type,跟前面的类型对象对比,他没有设置tp_base字段记录继承信息,因为它要作为继承链的终点,防止进入死循环。

小结

到这里我们基本可以弄清楚python对象体系的关系。变量名指向一个实例对象,这个对象包含基本的pyobject,ob_type指向它的类型对象PyFloat_Object,这个类型对象的type字段中,指向的是类型的类型PyType_type对象,tp_base中记录着继承信息,基类是pyBaseObject_type,另外PyBaseObject_type是元类型的基类,PyType_Tpye是object的类型。

生命周期

接下来我们再了解一下对象的生命周期。

static PyObject *
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{PyObject *obj;//...obj = type->tp_new(type, args, kwds);obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);if (obj == NULL)return NULL;//...type = Py_TYPE(obj);if (type->tp_init != NULL) {int res = type->tp_init(obj, args, kwds);if (res < 0){assert(PyErr_Occurred());Py_DECREF(obj);obj = NULL;}else {assert(!PyErr_Occurred());}}return obj;
}

我们还记得类型对象中的tp_call字段,当对象被创建的时候会通过类型对象调用tp_call方法,这里先调用了tp_new申请内存,然后如果它有init的话会调用tp_init对对象进行初始化。这是两个比较关键的操作。

#define PyINCREF(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_PRECNT(op)else_Py_Dealloc((PyObject *)(op));} while (0)

对象的销毁是通过PyObject对象中的引用计数来判断的。刚才对象创建调用完tp_new方法之后,会执行增加引用计数的宏,然后init失败之后减少引用计数。这两个宏分别是Py_INCREF和Py_DECREF,可以看到都在操作pyObject中的记录引用次数的这个字段,在指针为零时还会会销毁或者回收对象。

不同的对象肯定有不一样的行为,通过行为可以把对象分成不同的类别。数值型的对象会有加减乘除等操作,序列型的对象有下标操作,关联型对象会产生约束。Python为每一个类别都定义了一个标准操作集。数值型对象比如int,float;序列型对象str,bytes,tuple,list;关联型对象dict
在类型对象PyTypeObject中,可以看到三个操作集的定义:type_as_number,type_as_sequence,type_as_mapping

typedef struct _typeobject
{PyObject_VAR_HEADconst char *tp_name;Py_ssize_t tp_basicsize, tp_itemsize;//...PyNumberMethods *tp_as_number;      //数值型操作PySequenceMethods *tp_as_sequence;   //序列型操作PyMappingMethods *tp_as_mapping; //关联型操作//...PyBufferProcs *tp_as_buffer;//...
} PyTypeObject;
static PyNumberMethods float_as_number = {float_add,float_sub,float_mul,float_rem,float_divmod,float_pow,//...
};
PyTypeObject PyFloat_Type = {PyVarObject_HEAD_INIT(&PyType_Type, 0)"float",sizeof(PyFloatObject),&float_as_number,    // tp_as_number0,                   // tp_as_sequence0,                 // tp_as_mapping
};

只要类型对象提供相关的操作集,实例对象就会有这些行为。以float为例可以看到:
在PyFloat_Tpye类型对象中,定义了数值型操作集,序列型和关联型都是空的,所以只支持数值型操作,float_as_number中也详细对应了float版本的函数,有加减乘取余,取模等等。

Python源码学习(一)相关推荐

  1. python源码学习_【Python学习】Python源码阅读(一)

    最近想读读Python源码,任何东西学习方法基本都是一样的,先从总体框架进行了解,再从自己侧重的方面逐步深入. 1. Python总体架构 左边是Python提供的大量的模块.库以及用户自定义的模块. ...

  2. Python源码学习笔记:Python程序执行过程与字节码

    Python程序执行过程与字节码 注:本篇是根据教程学习记录的笔记,部分内容与教程是相同的,因为转载需要填链接,但是没有,所以填的原创,如果侵权会直接删除. 问题: 我们每天都要编写一些Python程 ...

  3. Python源码学习:多线程实现机制

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 本文分析Python中的多线程机制,主要通过一个多线程的脚本来分析多线程的基本操作与 ...

  4. Python源码学习:Python类机制分析-用户自定义类

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 上一文,分析了Python在启动初始化时,对内置类的一个基本的初始化流程,本文就简析 ...

  5. Python源码学习:Python类机制分析

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 本文主要分析Python中类时如何实现的,在Python中,一切都是对象:任何对象都 ...

  6. Python源码学习:Python函数浅析-函数闭包

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 上一篇分析了函数参数的分析后,本文分析函数闭包的实现.函数闭包即函数定义和函数表达式 ...

  7. Python源码学习:Python函数浅析-有参函数

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 继续上一篇无参函数的调用后,本文将分析Python中的有参函数的大致流程,在Pyth ...

  8. Python源码学习:Python函数浅析-无参函数

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 本文会大致分析一下Python中的函数机制.在Python中,函数是一个比较重要的类 ...

  9. Python源码学习:内建类型简析并简析int对象

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> 上一篇文章中已经大致分析了下,Python的启动执行流程,现在我们分析一下Pytho ...

  10. Python源码学习:启动流程简析

    Python源码分析 本文环境python2.5系列 参考书籍<<Python源码剖析>> Python简介: python主要是动态语言,虽然Python语言也有编译,生成中 ...

最新文章

  1. 计算机专业PhD申请文书范文,美国留学博士申请文书怎么写之范文分享
  2. Linux Tomcat安装,Linux配置Tomcat,Linux Tomcat修改内存,Linux tomcat修改端口
  3. K3ERP连接数据库问题
  4. 深入理解ReactRedux
  5. 【Linux 内核】进程管理 ( 进程相关系统调用源码分析 | fork() 源码 | vfork() 源码 | clone() 源码 | _do_fork() 源码 | do_fork() 源码 )
  6. DOS调用21H存取中断向量
  7. 题解报告:hdu 4907 Task schedule
  8. php excel中解析显示html代码_骑士cms从任意文件包含到远程代码执行漏洞分析
  9. text-align:justify 使用参考
  10. oracle语法官方文档,Oracle官方文档必备语法知识
  11. 运行android程序时显示stop,Android系统.应用程序关闭时WorkManager是否正在运行?
  12. 生成指定大小的空文件
  13. python list 底层_深入Python列表的内部实现
  14. 微软开源 TensorFlow-DirectML,为 WSL2 提供 GPU 支持
  15. wdcp安装多种php版本共存
  16. HTML页面跳转及传递参数
  17. 弘玑Cyclone上榜36氪中国超自动化先锋企业
  18. JAVA 实现《黄金矿工》游戏
  19. android aidl oneway用法
  20. 通过three.js实现3d模型展示

热门文章

  1. 按键精灵两种方法对大漠进行注册regsvr32
  2. Mac下的plist纹理图切图工具(命令行)
  3. Daocloud配置文件使用(启动时替换配置文件)
  4. App ID注册地址
  5. Java基础知识学习笔记总结
  6. 三维空间中绘制点、线、面、UV贴图,万能的BufferGeometry(three.js实战4)
  7. 全新勒索病毒爆发:一样的套路这次没人上当了
  8. windows下的docker学习
  9. 风格迁移2020 —— 论文汇总——云盘分享
  10. 百度地图的鹰眼服务--Web上手