7

我目前正在学习基本的compsci课程。我们经常使用 Python in。我很好奇它是如何实现的,powers 的代码是什么in样的。

我可以想到如何实现这样的事情,但是我在交了几个家庭作业后学到的是,我的做事方式通常非常糟糕而且效率低下。所以我想开始调查“好” ' 代码。

4

4 回答 4

10

内置函数、类型和运算符等的问题是它们不是在 Python 中实现的。相反,它们是用 C 实现的,这是一种更加痛苦和冗长的编程语言,并不总是能很好地转换为 Python(通常是因为在 Python 中以其他方式更容易。)

话虽如此,您可以通过他们的公共源代码库在线调查 Python 的所有实现。

的实现in是分散的——每种类型都有一个实现,加上一个更通用的实现,它调用特定于类型的实现(稍后会详细介绍)。例如,对于列表,我们会寻找列表的实现。在 Python 源代码树中,所有内置对象的源代码都在 Objects 目录中。在该目录中,您会找到 listobject.c ,其中包含列表对象及其所有方法的实现。

在回答时的存储库中,如果您查看第 393 行,您会发现 in 运算符的实现(也称为__contains__方法,它解释了函数的名称)。这相当简单,只需遍历列表中的所有元素,直到找到该元素或没有更多元素,然后返回搜索结果。:)

如果它有帮助,在 Python 中写这个的惯用方式是:

def __contains__(self, obj):
    for item in self:
        if item == obj:
            return True

    return False

我之前说过,有一个更通用的实现。这可以在 in 的实现中PySequence_Contains看出abstract.c。它尝试调用特定于类型的版本,如果失败,则诉诸常规迭代。当您用 C 语言(使用 Python C-API)编写它时,该循环就是常规 Python for 循环的样子。

于 2012-04-21T16:34:27.637 回答
6

从 Python 语言参考的数据模型部分:

成员资格测试运算符 (innot in) 通常实现为通过序列的迭代。但是,容器对象可以提供以下具有更有效实现的特殊方法,这也不需要对象是序列。

object.__contains__(self, item)

调用以实现成员资格测试运算符。如果项目在自身中,则应返回 true,否则返回 false。对于映射对象,这应该考虑映射的键而不是值或键项对。

对于未定义__contains__()的对象,成员资格测试首先尝试迭代 via __iter__(),然后尝试旧的序列迭代协议 via __getitem__(),请参阅语言参考中的此部分。

So, by default Python iterates over a sequence to implement the in operator. If an object defines the __contains__ method, Python uses it instead of iterating. So what happens in the __contains__ method? To know exactly, you would have to browse the source. But I can tell you that Python's lists implement __contains__ using iteration. Python dictionaries and sets are implemented as hash tables, and therefore support faster membership testing.

于 2012-04-21T16:36:38.650 回答
2

Python 的内置方法是用 C 语言编写的——您可以通过自己查看 Python 的源代码来查看它们的代码。

但是,如果您想查看 Python 本身中所有方法的等效实现,您可以查看PyPy - 它具有 100% 用 Python 编写的 Python 实现及其子集 (rpython)。

in运算符在字符串对象中调用该方法__contains__——因此您可以检查两个项目中字符串的实现——但实际的搜索代码将被埋得更深。

这是 CPython 中的一些代码,例如:

http://hg.python.org/cpython/file/c310233b1d64/Objects/stringlib/fastsearch.h

于 2012-04-21T16:33:00.213 回答
0

您可以在线浏览 Python-Source:http: //hg.python.org/

一个好的开始是克隆您需要的存储库,然后使用它grep来查找您需要的东西。

于 2012-04-21T16:28:14.237 回答