2024年最全python源码解读_python代码解释

2024年最全python源码解读_python代码解释endif endif endifPyObjec ifNSMALLNEGI NSMALLPOSINT 尝试使用小整数对象池 endif 有一个看似不合适但是比较方便的

大家好,欢迎来到IT知识分享网。

 主要是`PyIntObject`和`PyInt_Type`,其他和普遍的PyObject, PyTyoeObject没什么,值得关注的有 * python2中稍小一点的数直接用C语言中的long去存储,稍大一点的数(超过long的承受范围)会使用python的long对象去存储,而python3不会作区分,统一用longObect去存储,实现用到了`柔性数组`,感兴趣可以查一下 * 小整形数组的内存池和大整形对象的内存链的维护,避免频繁malloc 在Python中,整数的使用是很广泛的,对应的,它的创建和释放也将会很频繁,那么如何设计一个高效的机制,使得整数对象的使用不会成为Python的瓶颈?在Python中是使用整数对象的缓冲池机制来解决此问题。使用缓冲池机制,那意味着运行时的整数对象并不是一个个独立的,而是相关联结成一个庞大的整数对象系统了。 小整形对象 
 在实际的编程中,数值比较小的整数,比如1,2,等等,这些在程序中是频繁使用到的,而Python中,所有的对象都存活在系统堆上,也就是说,如果没有特殊的机制,对于小整数对象,Python将一次次的malloc在堆上申请空间,然后free,这样的操作将大大降低了运行效率。 那么如何解决呢?Python中,对小整数对象使用了对象池技术。 那么又有一个问题了,Python中的大对象和小对象如何区分呢?嗯,Python中确实有一种方法,用户可以调整大整数和小整数的分界点,从而动态的确定小整数的对象池中应该有多少个小整数对象,但是调整的方法只有自己修改源代码,然后重新编译。 大整数对象 对于小整数,小整数对象池中完全的缓存PyIntObject对象,对于其它对象,Python将提供一块内存空间,这些内存空间将由这些大整数轮流使用,也就是谁需要的时候谁使用。 比如,在Python中有一个PyIntBlock结构,维护了一块内存,其中保存了一些PyIntObject对象,维护对象的个数也可以做动态的调整。在Python运行的某个时刻,有一些内存已经被使用,而另一些内存则处于空闲状态,而这些空闲的内存必须组织起来,那样,当Python需要新的内存时,才能快速的获得所需的内存,在Python中使用一个单向链表(free\_list)来管理所有的空闲内存。 

typedef struct _intblock PyIntBlock;

 创建 如果小整数对象池机制被激活,则尝试使用小整数对象池;如果不能使用小整数对象池,则使用通用整数对象池。 可以创建int的代码理解这两块的使用 
 下面是关于freelist的申请,和freelist和block\_list的维护有关的代码 
 这样,freelist会指向可以分配内存的地址,但是如果由之前分配的PyIntObject被释放了,freelist需要将被释放的地址重新使用才可以,这个是通过PyIntObect的析构函数来实现的 
 Python中的字符串对象 PyStringObject和PyString\_Type 
 > > * `ob_sval`指的是一段长度为ob\_size+1个字节的内存,必须满足ob\_sval[ob\_size] == ‘\0’ > * `ob_shash`是`缓存`的该对象的`hash`值 > * `ob_sstate`标记了该对象是否已经经过intern机制的处理 > > > 创建PyStringObject对象 
size = strlen(str); if (size > PY_SSIZE_T_MAX) { return NULL; } if (size == 0 && (op = nullstring )!= NULL) { // intern机制: 和下面的一个分支都是为了缓存特定的对象,一个是空字符串,一个是单个字符字符串,第一次使用后会存在,之后不必再次创建PyObject对象(这些对象之前都被初始化成了NULL) return (PyObject \*) op; } if (size == 1 && (op = characters[\*str & UCHAR_MAX]) != NULL) { return (PyObject \*) op; } op = (PyStringObject \*)PyObject\_MALLOC(sizeof(PyStringObject) + size); // 加上包含'\0'的额外内存 PyObject\_INIT\_VAR(ob, &PyString_Type, size); op->ob_shash=-1; op->ob_sstate=SSTATE_NOT_INTERNED; memcpy(op->ob_sval, str, size+1); if (size==0) { PyObject \*t = (PyObject \*) op; PyString\_InternInPlace(&t); op = (PyStringObject \*) t; nullstring = op; } else if (size == 1) { PyObject \*t = (PyObject \*) op; PyString\_InternInPlace(&t); op = (PyStringObject \*) t; characters[\*str & UCHAR_MAX] = op; } return (PyObejct \*) op; 

}

 ![在这里插入图片描述](https://img-blog.csdnimg.cn/.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2NTgxOTYx,size_16,color_FFFFFF,t_70) 字符串对象的intern机制 
 > > characters 是静态变量static PyStringObject \*characters[UCHAR\_MAX+1]; 开始都是NULL指针 > = join字符串效率比 + 好, 因为PyStringObject 是不可变对象(varObject只是因为是变长的),两者申请内存不同 > join 计算所有 PyStringObject 的size 得出需要分配的内存,一次分配 > = 而concat(+) 需要分配n-1次内存,并且伴有析构 > > > python中的List对象 
 实际的操作和c++ vector类似略。有一个比较特别的是free\_list的维护 

define MAXFREELISTS 80

 python中的Dict对象 实现是散列表,采用二次探针解决冲突 
 `entry` 会有三种状态 dummy状态是探测连上的元素伪删除后的状态 ![在这里插入图片描述](https://img-blog.csdnimg.cn/.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2NTgxOTYx,size_16,color_FFFFFF,t_70) 
 其他包括缓冲池之类的会和list类似,lookup这块会多点东西。 python提供了两种搜索策略,一个lookdict一个lookdict\_string 

在这里插入图片描述

感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:

① 2000多本Python电子书(主流和经典的书籍应该都有了)

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且经典的练手项目及源码)

④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112091.html

(0)
上一篇 2026-01-20 18:33
下一篇 2026-01-20 19:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信