python源码笔记_python源码学习笔记(一)
(一)python对象的基本实现
众所周之,python是个极其简洁高效的脚本语言,其设计思维之简洁,编写之简单,已成公认。想着深入了解内部机制,探索一下源代码,并记录一些东西。诚然,人总是健忘的,因而只有不断地写日记和笔记记录自己的想法,我们的有益的想法和生活的点滴才能被永久地保存下来,否者只能在别人思想的轨道上空转,始终成为不了自己的东西。
当然对于现存的事物,我们最好或者一定要采取critica thingking的态度。准备考试,最大的痛苦就是要照抄全搬,头脑越学越死。当时归根到底我们学习不是为了考试,不是为了分数,更重要的是提高自己的capability。
python源码的注释很清楚,或者说很人性化,而且事实上也不会出现艰难晦涩的算法,最主要的还是设计的思想和框架。当然宏神马的很讨厌,窜来窜去的...
学习python的第一步就是要了解其工作机制,下面开始记录:
所谓对象,实际上是把一块数据集及针对数据的操作当做为一个整体,非常符合人的思维,比如开关灯,灯、开关就是数据,打开开关就是操作。
首先,python都有个根对象即PyObject, 采用引用计数的方式,当ob_refcnt=0时,从堆中删除对象,释放出内存供别的对象使用。对于可变大小的Object称为PyVarObject, 这样的对象通常都是Container, 在PyObject_VAR_HEAD中有个ob_size这个变量,表明有多少个对象在容器中。具体定义如下
1 [object.h]2 #ifdef Py_TRACE_REFS3 /*Define pointers to support a doubly-linked list of all live heap objects.*/
4 #define _PyObject_HEAD_EXTRA \
5 struct _object *_ob_next; \6 struct _object *_ob_prev;7
8 #define _PyObject_EXTRA_INIT 0, 0,
9
10 #else
11 #define _PyObject_HEAD_EXTRA
12 #define _PyObject_EXTRA_INIT
13 #endif
14
15 /*PyObject_HEAD defines the initial segment of every PyObject.*/
16 #define PyObject_HEAD \
17 _PyObject_HEAD_EXTRA \18 Py_ssize_t ob_refcnt; \ //引用计数
19 struct _typeobject *ob_type;20
21 #define PyObject_HEAD_INIT(type) \
22 _PyObject_EXTRA_INIT \23 1, type,24
25 #define PyVarObject_HEAD_INIT(type, size) \
26 PyObject_HEAD_INIT(type) size,27 ....28
29 typedef struct_object {30 PyObject_HEAD31 } PyObject;32
33 typedef struct{34 PyObject_VAR_HEAD35 } PyVarObject;
python 中还有一个比较关键的就是类型对象的定义,像C里面有内置的int , double 一样,python 里也需要内置的对象
接着我们会看到_typeobject 的定义
1 [object.h]2 typedef struct_typeobject{3 PyObject_VAR_HEAD //注意这里也有对象头
4 char *tp_name; //for printing
5 inttp_basicsize, tp_itmesize;6
7
8 //methods
9 destructor tp_dealloc;10 printfunc tp_print;11 .....12
13
14 //more
15 hashfunc tp_hash;16 ternaryfunc tp_call;17 ....18
19 } PyTypeObject;
与类型相关联的操作信息一般采取函数指针的形式 ,例如 typedef long (*hashfunc)(PyObject *);这些操作分为 标准操作(dealloc, print , compare),标准操作族(numbers, sequences, mappings) 以及其他操作(hash, buff, call)
另外,值得我们注意的是_typeobject也是个对象,其类型为PyType_Type
1 [typeobject.c]2
3 PyTypeObject PyType_Type ={4 PyObject_HEAD_INIT(&PyType_Type)5 0,6 "type",7 sizeof(PyHeadTypeObject),8 sizeof(PyMemberDef),9 ....10 PyObject_GC_Del,11 (inquiry) type_is_gc,12
13 };14 //以一个整数对象为例:15 PyTypeObject PyInt_Type ={16 PyObject_HEAD_INIT(&PyType_Type)17 0,18 "int",19 sizeof(PyIntObject),20 ...21 };
紧接着我们会留意到针对PyObject一系列的宏,首先是:
1 #define _Py_NewReference(op) ( \
2 _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \3 _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \4 Py_REFCNT(op) = 1)5
6 #define _Py_ForgetReference(op) _Py_INC_TPFREES(op)
7
8 #define _Py_Dealloc(op) ( \
9 _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \10 (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op)))11 #endif /* !Py_TRACE_REFS */
12
13 #define Py_INCREF(op) ( \
14 _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \15 ((PyObject*)(op))->ob_refcnt++)16
17 #define Py_DECREF(op) \
18 do{ \19 if(_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \20 --((PyObject*)(op))->ob_refcnt != 0) \21 _Py_CHECK_REFCNT(op) \22 else\23 _Py_Dealloc((PyObject *)(op)); \24 } while (0)25
第一个是新建对象引用,即初始化ob_refcnt=1,很有意思哈,连comma——','都被宏定义了,然后是丢弃对象引用:
1 #define _Py_INC_TPFREES(OP) dec_count(Py_TYPE(OP))
然后是对对象引用的自增、自减操作。当ob_refcnt=0时,调用析构函数,即tp_dealloc。另外如果OP是个NIL,必须使用Py_XINCREF/Py_XDECREF。基本非常基础的内容,比较浅显,是python设计的开始,和MFC的原理有点类似,PyObject对应CObject。
python源码笔记_python源码学习笔记(一)相关推荐
- python测试自动化封装_python接口自动化学习笔记(封装获取测试数据方法)
本篇文章是接于python接口自动化学习笔记(封装方法用于读取excel) 后的拓展,讲解在封装完成excel的数据读取代码后,如何在data层进行使用 首先,我准备了这样一个excel表格用以存储测 ...
- 对python的评价语_Python自然语言处理学习笔记之评价(evaluationd)
对模型的评价是在test set上进行的,本文首先介绍测试集应该满足的特征,然后介绍四种评价方法. 一.测试集的选择 1.首先,测试集必须是严格独立于训练集的,否则评价结果一定很高,但是虚高,不适用于 ...
- python locust提取参数_python+locust性能测试学习笔记
前言 Locust(俗称 蝗虫)一个轻量级的开源压测工具,基本功能是用Python代码描述所有测试.不需要笨拙的UI或庞大的XML,只需简单的代码即可. 环境安装 Locust支持Python 2.7 ...
- python第三周笔记_Python第四周 学习笔记(1)
函数 Python的函数没有return语句,隐式会返回一个None值 函数是可调用的对象,callable() 函数参数 参数调用时传入的参数要和定义的个数相匹配(可变参数例外) 位置参数 def ...
- python量化交易学习笔记_Python量化交易学习笔记(45)——深度学习挖短线股5
前4篇文章分别记录了利用深度学习挖短线股的数据预处理.模型训练.结果预测及策略回测过程,本文记录根据筛选短线股票的过程. 选股流程 1.股票数据下载更新 例如现在是2020年11月23日19:00,我 ...
- python quit函数作用_Python常用函数学习笔记
Python函数很多,常用的函数不同的场景侧重不同,学而时习之,不亦乐乎? abs # 求绝对值 Capitilize函数: # 有列表 li = ['aB', 'egon', 'smith', 'p ...
- python网络编程库_python网络编程学习笔记(9):数据库客户端
一.DB-API概述 python支持很多不同的数据库.由于不同的卖家服务器导致和数据库通信的网络协议各有不同.在python的早期版本中,每一种数据库都带有自己的python模块,所有这些模块以不同 ...
- python自然语言处理评论_python自然语言处理——学习笔记:Chapter3纠错
2017-12-06更新:很多代码执行结果与书中不一致,是因为python的版本不一致.如果发现有问题,可以参考英文版: 第三章,P87有一段处理html的代码: >>>raw =n ...
- python元组怎么使用_Python 2.7 学习笔记 元组的使用
一.元组 python中的元组和列表非常类似,核心区别是元组的内容初始化后是不可以修改的,而队列可以. 关于列表的详细介绍,可查看上一篇列表使用文章. 大部分场景下,能用元组的地方,都可以用列表.但有 ...
- python modbus tk 库_python modbus_tk模块学习笔记(rtu slaver例程)
GIT地址:https://github.com/ljean/modbus-tk 找到modbus rtu slaver 例程 用宝塔将例程复制到centos目录 #!/usr/bin/env pyt ...
最新文章
- java和python哪个好学-学java好还是Python好?
- web标准常见问题整理
- 常用Git命令清单。
- WeChall_PHP-htmlspecialchars
- 编写一个C程序,实现以下功能:编写一个常规的函数和一个递归函数,两个函数均能将输入的一个字符串以按反序形式的字符串作为返回值。在main函数中输入一行字符串,分别调用两个函数,输出反序后的字符串。
- 如何禁止使用bottomsheetdialogfragment拖动?
- linux tomcat启动nohup,linux下tomcat添加服务
- Linux 系统目录详解
- ZPL指令打印 斑马打印机指令打印
- db link hang的解决方法
- BFS POJ 3278 Catch That Cow
- 【语音处理】基于matlab GUI音频信号处理(调音+调速+调频+滤波)(带面板)【含Matlab源码 299期】
- 51单片机DS1302时钟
- 计算机键盘上如何打对勾,电脑键盘怎么打对勾符号
- dynamic k-max pooling 动态k-max 池化
- Android开发学习之路III-服务器技术篇
- P1347 排序(topo)
- Jmeter性能测试之系统监控
- 叮叮书店 about.html,网页编程HTML+CSS网站设计
- 用ruby实现latex自动编译
热门文章
- IAR stm8 调试时无法看到局部变量解决
- PHP学习笔记八【数组】
- 使用内部(com.android.internal)和隐藏(@hide)API[第4部分,定制ADT]
- ant的设置properties
- .net remoting 与webservice
- c# UDP(udpclient)客户端和服务端有何区别?
- swift5 实现录音App
- IOS笔记CALayer的position和anchorPoint
- C语言编写工资管理系统类似学生管理系统
- python提取图片gps坐标_用python从.docx文件中提取GPS坐标