08-解密Python中列表的底层实现
08-解密Python中列表的底层实现楔子Python中的列表可以说使用的非常广泛了,在初学列表的时候,老师会告诉你列表就是一个大仓库,什么都可以存放。不过在最开始的几个章节中,我们花了很大的笔墨介绍了Python中的对象,并明白了Python中变量的本质,我们知道列表中存放的元素其实都是泛型指针PyObject *,所以到现在列表已经没有什么好神秘的了。
并且根据我们使用列表的经验,我们可以得出以下两个结论:
每个列表中的元素个数可以不一样:所以这是一个变长对象
可以对列表中的元素进行添加、删除、修改等操作,所以这是一个可变对象
在分析列表对应的底层结构之前,我们先来回顾一下列表的使用。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455# 创建一个列表,这里是通过Python/C API创建的>>> lst = [1, 2, 3, 4]>>> lst[1, 2, 3, 4]# 往列表尾部追加一 ...
07-Python字符串的底层实现
07-Python字符串的底层实现楔子这一次我们分析一下Python中的字符串,首先Python中的字符串是一个变长对象,因为不同长度的字符串所占的内存空间是不一样的;但同时字符串又是一个不可变对象,因为一旦创建就不可以再修改了。
而Python中的字符串是通过unicode来表示的,因此在底层对应的结构体是PyUnicodeObject。但是为什么需要unicode呢?
首先计算机存储的基本单位是字节,由8个比特位组成,由于英文字母算上大小写只有52个,再加上若干字符,数量不会超过256个,因此一个字节完全可以表示,这些字符称之为ASCII字符。但是随着非英文字符的出现,导致一个字节已经无法表示了,只能曲线救国,对于一个字节无法表示的字符,使用多个字节表示。
但是这样会出现两个问题:
不支持多国语言,例如中文的编码不可以包含日文;
没有统一标准,例如中文有GB2312、GBK、GB18030等多个标准;
所以由于编码不统一,开发人员经常在不同的编码间来回转换,会错误频出。为了彻底解决这个问题,unicode标准诞生了。unicode对世界上的文字系统进行了系统的整理、编码,让计 ...
06-Bytes对象的底层操作
06-Bytes对象的底层操作楔子不少编程语言中的”字符串”都是使用字符数组(或者称字符序列)来表示,比如C语言和go语言就是这样。
1char name[] = "komeiji satori";
一个字节最多能表示256个字符,所以对于英文来说足够了,因此一个英文字符占一个字节即可,然而对于那些非英文字符便力不从心了。因此为了表示这些非英文编码,于是多字节编码应运而生—-通过多个字节来表示一个字符。但由于原始字节序列不维护编码信息,因此操作不慎便导致各种乱码现象。
而Python提供的解决方案是使用unicode(在Python3中等价于str)表示字符串,因为unicode可以表示各种字符,不需要关心编码的问题。但在存储或网络通讯时,字符串不可避免地要序列化成字节序列。为此,Python除了提供字符串对象之外,还额外提供了字节序列对象—-bytes。
如上图,str对象统一表示一个字符串,不需要关心编码;计算机通过字节序列和存储介质、网络介质打交道,字节序列由bytes对象表示;在存储和传输str对象的时候,需要将其序列化成字节序列,序列化也是编码的过程。 ...
05-Python整数的底层实现
05-Python整数的底层实现这次我们来分析一下Python中的整数是如何实现的,我们知道Python中的整数是不会溢出的,换句话说,它可以计算无穷大的数。只要你的内存足够,它就能计算,但是对于C来说显然是不行的,可Python底层又是C实现的,那么它是怎么做到整数不会溢出的呢?
既然想知道答案,那么看一下Python中的整型在底层是怎么定义的就行了。
int实例对象的底层实现Python中的整数底层对应的结构体是PyLongObject,它位于longobject.h中。
12345678910111213141516171819202122//longobject.htypedef struct _longobject PyLongObject; /* Revealed in longintrepr.h *///longintrepr.hstruct _longobject { PyObject_VAR_HEAD digit ob_digit[1];};//合起来可以看成typedef struct { PyObject_VAR_H ...
04-浮点数的底层实现
04-浮点数的底层实现从现在开始,我们就来分析Python中常见的内置对象、以及对应的实例对象,看看它们在底层是如何实现的。但说实话,我们在前面几节中介绍对象的时候,已经说了不少了,不过从现在开始要进行更深入的分析。
除了对象本身,还要看对象支持的操作在底层是如何实现的。我们首先以浮点数为例,因为它是最简单的,没错,浮点数比整型要简单。至于为什么,当我们分析整型的时候就知道了。
内部对象float实例对象定义在Include/floatobject.h中,结构非常简单:
12345//Include/floatobject.htypedef struct { PyObject_HEAD double ob_fval;} PyFloatObject;
除了PyObject这个公共的头部信息之外,只有一个额外的ob_fval,用于存储具体的值,而且直接使用的C中的double。
那么float类型对象在底层长啥样子呢?
与实例对象不同,float类型对象全局唯一,因此可以作为全局变量定义。底层对应PyFloat_Typ ...
03-Python引用计数器和底层对象管理
03-Python引用计数器以及底层对象管理在上一篇中我们说到了Python中的对象在底层的数据结构,我们知道Python底层通过PyObject和PyTypeObject完成了C++所提供的对象的多态特性。在Python中创建一个对象,会分配内存并进行初始化,然后Python会用一个PyObject *来保存和维护这个对象,当然所有对象都是如此。因为指针是可以相互转化的,所以变量在保存一个对象的指针时,会将该指针转成PyObject *之后再交给变量保存。因此在Python中,变量的传递(包括函数的参数传递)实际上传递的都是一个泛型指针:PyObject *。这个指针具体是指向的什么类型我们并不知道,只能通过其内部的ob_type成员进行动态判断,而正是因为这个ob_type,Python实现了多态机制。
比如:a.pop(),我们不知道这个a指向的对象到底是什么类型,但只要a可以调用pop方法即可,因此a可以是一个列表、也可以是一个字典、或者是我们实现了pop方法的类的实例对象。所以如果a的ob_type是一个PyList_Type *,那么就调用PyList_Type中定义的p ...
02-一切对象皆PyObject
02-一切皆对象PyObject一切皆对象PyObjectPython中一切皆对象,int str list dict tuple都是对象,类型也是对象。程序员可以通过class创建自己的对象,对象对于程序员来说是数据,对计算机来说是一块内存。
Python中还有一个特殊的类型(对象),叫做object,它是所有类型对象的基类。不管是什么类,内置的类也好,我们自定义的类也罢,它们都继承自object。因此,object是所有类型对象的”基类”、或者说”父类”。
我们说可以使用type和__class__查看一个对象的类型,并且还可以通过isinstance来判断该对象是不是某个已知类型的实例对象;那如果想查看一个类型对象都继承了哪些类该怎么做呢?我们目前都是使用issubclass来判断某个类型对象是不是另一个已知类型对象的子类,那么可不可以直接获取某个类型对象都继承了哪些类呢?
答案是可以的,方法有三种,我们分别来看一下:
123456789101112131415161718class A: passclass B: passclass C(A): passclass D(B, ...
01-编译Cpython
01-编译CPythonCPython的目录结构源码中文件夹的大致含义如下:
12345678910111213141516cpython/│├── Doc ← Source for the documentation├── Grammar ← The computer-readable language definition├── Include ← The C header files├── Lib ← Standard library modules written in Python├── Mac ← macOS support files├── Misc ← Miscellaneous files├── Modules ← Standard Library Modules written in C├── Objects ← Core types and the object model├── Parser ← The Python parser source code├── PC ← Windows build s ...
通过NPM生态系统的依赖树揭开脆弱性传播及其演化的神秘面纱
d9eba399523fe401e434f6396d459a7ac85bda134c4f41e6609feedbaf3c389f92cf32df8a885d51d6373862fcd78fef8e430fd54da1504eb728a4067c823bd5ef781e9fc55bd693454e9dfaaed5cf5e47f221f5172c92b2bd5b69e8c05f29cb4b6ffd461b3e0bd9cf9b5c69df412ddb4fea8c1ddc30ad07db839d5494d557e0d16f845548d0cde6d958711dc8b38d8cc09805b16fbfdcdb55b27b53c6d863144f73eba9545c1a021ceaafcfb33fc7f3d28d0208de6047b0365b09d5a7795e970545ab68fa9d9311258af385619e57d5df3ced46ece1313a36eac05a5fab31c1815ec2dd215a62e0f7c9ca7d88899f87e6ca1bcd49b1a5bbd ...
PLUMBER
d9eba399523fe401e434f6396d459a7ac85bda134c4f41e6609feedbaf3c389f9caf80b8d8e7ab0b70eddd59ade545a0cca4f567d8f3f6b1f757ea67a1a80a4c2a0aea23774d2acb91fb6183a7819ca92b39bb3641496c4c7a841a974810bddf50c0439d843fd42bfb3b6ad10768012cd1fa31d9b2b6103094fc54b3715a8c6842d1429e1a3a92512d9c4d8b64d35ea9d758be9155fd573a0aab31f44d88239d27ed51513b110294293851aa701592371b7e8f7a0f6cea6b40336f8519f79c1cc34b17db22647bcea0ee23e40d4530ba703dcac3b8883391e9586d7ba769b102bc68dcbe71665d32e64b618e80c777e48fa6b397d4f8cbe00 ...