Python源码探究

以str.find为例

Posted by pfan8 on May 4, 2020

背景

在做Leetcode中字符串匹配的题目时,突然想知道Python中内置函数str.find的实现方法,就开始搜索查看Python源码。另外一方面,其实之前就想查看一些Python源码,一直没时间研究,今天就把这个问题好好研究一下。

非cpython代码查看

通过help(module)moduleimport的包名称,根据FILE的路径即可查看到源码,只要是python实现的API,都能通过该方式查看

cpython代码查看

python很多内置代码都是C++实现的,为了运行速度,不然最初python的运行速度实在是惨不忍睹……但是C++的代码你怎么查看呢,这些builtin的代码通过python是看不到的,你只能看到builtins中API的接口定义,C++的部分已经编译成二进制了(应该,不确定),所以要看源码只能是官方公布代码才行。

所幸Python是开源的,C++的部分也放在GitHub上可以直接搜索看到,Python的C++内核部分称为Cpython,GitHub的链接如下:https://github.com/python/cpython/blob/master/Objects/stringlib/fastsearch.h

str.find的实现就在fastsearch中,在objects的stringlib里,找了半天(捂脸)。有点好奇为什么在h头文件中实现,高级的C++写法,还不懂。

看注释可以看到说了是结合boyer-moore和horspool实现的


/* fast search/count implementation, based on a mix between boyer-
moore and horspool, with a few more bells and whistles on the top.
for some more background, see: http://effbot.org/zone/stringlib.htm */

代码我没有仔细看,大致知道用的算法即可,关于字符串匹配的算法可以查看本人的LeetCode总结文章

源码Example(持续更新)

最近又想看看Python一些内置函数的实现,我想以后可能还会有这样的需求,所以就放到这个位置持续更新吧

min()

min函数相信没有人没用过,但是他怎么实现的我也肯定99%的Python用户不知道。同样是做一道求最小值的LeetCode题的时候,我很好奇Python是怎么实现的,因为min是所有答案里速度最快的

这次在github上还不好查找,我直接把cpython的代码clone下来了,在vscode里找半天,最后找到一个min_max(),关键实现如下

int cmp = PyObject_RichCompareBool(val, maxval, op);
if (cmp < 0)
    goto Fail_it_item_and_val;
else if (cmp > 0) {
    Py_DECREF(maxval);
    Py_DECREF(maxitem);
    maxval = val;
    maxitem = item;
}
else {
    Py_DECREF(item);
    Py_DECREF(val);
}

cmp就是比较函数,基于设计模式原则,这样写会更易于修改。很明显,maxval就是遍历判断是否比当前值大,大的话就更新,很brute-force,但是它就是最快的!看来是因为c++代码的原因了,不然这实在没理由比BS快(针对LeetCode那道题)。不过又知道了一个常用函数的实现,感觉还是挺棒的~