《Python源码剖析》
1. Python内建对象
对象是数据以及基于这些数据的操作的集合,在Python中,对象就是为C中的结构体在堆上申请的一块内存。
在Python中,一个对象一旦被创建,它在内存中的大小就是不变的了,那些需要容纳可变长度数据的对象只能在对象内维护一个指向一块可变大小的内存区域的指针。
1.1.1 对象机制的基石 -- PyObject
[object.h]
typedef struct _object{int ob_refcnt; /* 引用计数器 */struct _typeobject *ob_type; /* _typeobject这个结构体用来指定一个对象类型的类型对象 */} PyObject
在Python中,对象机制的核心非常简单,一个是引用计数,一个是类型信息
在PyObject中定义了每一个Python对象都必须有的内容,除了PyObject以外,还应该有一些额外的内存,放置其他信息。
1.1.2 定长对象和变长对象
Python整数对象PyIntObject
typedef struct{PyObject_HEADlong ob_ival;} PyIntObject
整数对象的特殊信息是一个C中的整形变量,无论这个整数对象的值有多大,都可以保存在这个整形变量中。
变长对象PyVarObject
#define PyObject_VAR_HEAD \PyObject_HEAD \int ob_size; /* 容器中元素的数量 */typedef struct{PyObject_VAR_HEAD} PyVarObject;
我们把整形对象这样不包含可变长度数据的对象称为“定长对象”,而字符串对象这样包含可变长度数据的对象称为“变长对象”,它们的区别在于定长对象的不同对象占用内存大小是一样的,而变长对象的不同对象占用内存可能不一样。
PyVarObject只是对PyObject的一个扩展而已,在Python内部,每一个对象都拥有相同的对象头部。
1.2 类型对象
创建对象的时候,必须知道要申请多大的空间,所需空间大小是对象的一种元信息,这样的元信息与对象所属类型密切相关。我们考察一下类型对象_typeobject:
typedef struct _typeobject {PyObject_VAR_HEADchar *tp_name; /* tp_name 类型名 */int tp_basicsize, tp_itemsize; /* 创建该类型对象时分配内存空间的大小 *//* 与对象关联的操作信息 */destructor tp_dealloc;printfunc tp_print;/* 更多操作信息 */ hashfunc tp_hash;ternaryfunc tp_call;...} PyTypeObject;
一个PyTypeObject就是Python中面向对象理论中“类”这个概念的实现
1.2.1 对象的创建
Python创建对象的方法:
- 通过Python C API来创建
- 通过类型对象 PyInt_Type来创建
Python对外提供了C API让用户可以从C环境中与Python交互,Python的C API分为两类:
- 范型API,或称为AOL
- 另一类称为COL
从PyInt_Type创建整数对象
说明: 在Python完成运行环境的初始化后,符号'int'就对应着Python内部的PyInt_Type对象,object则对应着PyBaseObject_Type对象
- 使用init(10)创建对象时,就会调用PyInt_Type对象中的tp_new操作
- 假如这一个tp_new操作不存在,为NULL,那么就到tp_base指定的基类里去找tp_new操作
- 在Python2.2以后的新式类中,所有的类都是以object为基类的,所以最终一定可以找到一个不为NULL的tp_new
- tp_new指向了object_new,object_new会访问PyInt_Type中记录的tp_basicsize信息,得到需要申请的内存大小,然后完成申请内存的操作。我们前面说了,“在Python中,对象就是为C中的结构体在堆上申请的一块内存”,所以内存申请完成就代表对象已经创建(但还未初始化)
- tp_new创建完对象后,流程转向PyInt_Type的tp_init,完成初始化工作
当我们用int(10)创建整数对象10时,首先PyInt_Type中的tp_new会被调用,如果这个tp_new为NULL,那么会到tp_base指定的基类中去寻找tp_new操作
1.2.2 对象的行为
在PyTypeObject中定义了大量的函数指针,这些函数都最终会指向某个函数,或者指向NULL,这些函数指针可以视为类型对象中所定义的操作,而这些操作直接决定着一个对象在运行时所表现出的行为。
比如PyTypeObject中的tp_hash是一个函数指针(hashfunc)类型的变量,tp_hash指明对于该类型的对象如何生成其hash值。
在PyTypeObject中指定的不同的操作信息也正是一种对象区别于另一种对象的关键所在。
在这些操作族中,有三组非常重要:
tp_as_number
指向PyNumberMethods函数族,该族定义了一个数值对象应该支持的操作,典型对象如int,tp_as_number.nb_add指定了
对该对象进行加法操作时的具体行为。
tp_as_sequence
指向PySequenceMethods函数族,该族定义了作为一个序列对象应该支持的操作,典型对象list.
tp_as_mapping
指向PyMappingMethods函数族,该族定义了作为一个关联对象应该支持的操作,典型对象dict。
对一种类型来说,它完全可以同时定义三个函数族中的所有操作,只要定义相应的special_method
1.2.3 类型的类型
在Python中类型其实也是一个对象,类型的类对应Python内部的PyType_Type,它是所有class的class,在Python中称为metaclass,元类。
此处留疑问??????????????
[object.h]
#ifdef Py_TRACE_REFS#define _PyObject_EXTRA_INIT 0,0,
#else#define _PyObject_EXTRA_INIT
#endif#define PyObject_HEAD_INIT(type) _PyObject_EXTRA_INIT 1, type
番外篇: #define学习
\反斜杠把该定义延续到下一行,编译器将\分成的多个物理行转换为一个逻辑行,并删除\符号
#define预处理器指令以#号作为一行的开始,指令可以出现在源文件的任何地方,其定义从指令出现的地方到该文件末尾有效。
每行#define(逻辑行)都由3部分组成:
- 第1部分是#define指令本身
- 第2部分是选定的缩写,也称为宏,有些宏代表值,这些宏被称为类对象宏
- 第3部分称为替换列表或替换体
从宏变成最终替换文本的过程称为宏展开
在#define中使用参数可以创建外形和作用与函数类似的类函数宏
转载于:https://www.cnblogs.com/huangke/p/7883347.html
《Python源码剖析》相关推荐
- ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)
视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...
- ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析
视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...
- 信息学奥赛真题解析(玩具谜题)
玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...
- 信息学奥赛之初赛 第1轮 讲解(01-08课)
信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...
- 信息学奥赛一本通习题答案(五)
最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...
- 信息学奥赛一本通习题答案(三)
最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...
- 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题
第1章 快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章 素数 第 3 章 约数 第 4 章 同余问题 第 5 章 矩阵乘法 第 6 章 ...
- 信息学奥赛一本通题目代码(非题库)
为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...
- 信息学奥赛一本通(C++版) 刷题 记录
总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...
- 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离
首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...
最新文章
- uniapp里的mounted_uni-app 生命周期函数执行顺序
- PhoneGap 1.5版本 cordova.js 简析 3(转)
- 【数字信号处理】线性常系数差分方程 ( 概念 | 线性常系数差分方程解法 )
- 3.strcpy使用注意(3)
- 空except的慎用
- 模板匹配(Match Template)
- 加速 VR 渲染地狱难度进阶篇:降低图形 API 调用次数
- 如何使用jmeter进行并发登录测试
- 如何使用extern在源文件之间共享变量?
- 程序员提高编程能力万无一失的办法
- 数组遍历,判断数组中的对象中某一属性值时候为空
- 《BI那点儿事》Cube的存储
- Python+Wind:用 Pyautogui 轻松下载 Wind 数据
- 远程计算机上不接受445端口,服务器禁止远程445端口
- 使用WebGL和JavaScript构建地球
- Pickit 3D视觉定位抓取系统 -硅步机器人
- dw怎么做html鼠标变化,dw鼠标经过单元格变色 DW 鼠标经过表格 背景变色
- ajax下载Excel文件
- 在 Shell 脚本中调用另一个 Shell 脚本的三种方式
- 女生可以做软件测试吗?