我目前正在修读基础的compsci课程。我们经常使用Python的in
。我很好奇它是如何实现的,以及in
的代码是什么样的。
我可以想到我的如何实现这样的东西会起作用,但是我在完成一些家庭作业后学到的东西是我做事的方式通常非常糟糕和效率低下..所以我想开始调查'好'的代码。
答案 0 :(得分:10)
关于内置函数,类型和运算符等的事情是它们在Python中不实现。相反,它们是用C实现的,这是一种更加痛苦和冗长的编程语言,并不总能很好地转换为Python(通常因为在Python中其他方式更容易。)
话虽如此,您可以通过public source repository在线调查所有Python的实现。
in
的实现是分散的 - 每种类型都有一个实现,还有一个更通用的实现,它调用特定于类型的实现(稍后会详细介绍)。例如,对于列表,我们会查找列表的实现。在Python源代码树中,所有内置对象的源都在Objects目录中。在该目录中,您将找到listobject.c,其中包含列表对象及其所有方法的实现。
在回答时的存储库中,如果查看line 393,您将找到in运算符的实现(也称为__contains__
方法,它解释了函数的名称)。它相当简单,只是循环遍历列表的所有元素,直到找到元素,或者没有更多元素,并返回搜索结果。 :)
如果有帮助,在Python中写这个的惯用方法是:
def __contains__(self, obj):
for item in self:
if item == obj:
return True
return False
我之前说过,有一个更普遍的实施。这可以在abstract.c
中PySequence_Contains
的实现中看到。它尝试调用特定于类型的版本,如果失败,则转向常规迭代。当你在C语言中使用Python C-API编写它时,循环就会出现常规的Python for循环。
答案 1 :(得分:6)
来自Python语言参考的Data Model部分:
通常会实施成员资格测试运算符(
in
和not in
) 作为序列的迭代。但是,容器对象可以 提供以下特殊方法,效率更高 实现,也不要求对象是序列。
object.__contains__(self, item)
被调用以实现成员资格测试运营商。如果项目在自己,应该返回true, 否则是假的。对于映射对象,这应该 考虑映射的关键而不是值或 关键项对。
对于未定义
__contains__()
的对象,首先尝试成员资格测试 通过__iter__()
迭代,然后是旧的序列迭代 协议通过__getitem__()
,请参阅本节中的语言 参考
因此,默认情况下,Python迭代序列以实现in
运算符。如果对象定义了__contains__
方法,Python会使用它而不是迭代。那么__contains__
方法会发生什么?要确切地知道,您必须浏览the source。但我可以告诉你,Python的列表使用迭代实现__contains__
。 Python字典和集合实现为hash tables,因此支持更快的成员资格测试。
答案 2 :(得分:2)
Python的内置方法是用C语言编写的 - 您可以通过自己检查Python的源代码来查看它们的代码。
但是,如果你想看一下Python本身所有方法的等效实现,你可以检查PyPy - 其中包含100%用Python编写的Python实现及其子集(rpython) )。
in
运算符调用字符串对象中的__contains__
方法 - 因此您可以检查两个项目中字符串的实现 - 但实际搜索代码将被深埋。
以下是CPython中的一些代码,例如:
http://hg.python.org/cpython/file/c310233b1d64/Objects/stringlib/fastsearch.h
答案 3 :(得分:0)
您可以在线浏览Python-Source:http://hg.python.org/
一个好的开始是克隆您需要的存储库,然后使用grep
找到您需要的东西。