如何在Python源代码中找到运算符的定义?

8 投票
2 回答
730 浏览
提问于 2025-04-17 12:04

我对Python中“in”运算符(也就是__contains__)的实现产生了好奇,主要是因为这个问题。我下载了源代码,尝试用grep命令搜索、浏览等方式来找到它的基本定义,但一直没有成功。有人能告诉我怎么找到它吗?

当然,如果能提供一个通用的方法,那就更好了,这样像我这样的人下次也能自己找到。

我现在用的是2.7版本,但如果3.x版本的过程完全不同,那能提供两种方法就更好了。

2 个回答

2

根据Inerdial的建议,我开始深入研究这个问题。任何关于更好方法的反馈都非常欢迎。

ack --type=cc __contains__

这段代码指向了operator.c文件。

spam2(contains,__contains__,
 "contains(a, b) -- Same as b in a (note reversed operands).")

在这个文件中,“contains”被重命名为“op_contains”,而这个“op_contains”又指向了PySequence_Contains(这个函数不在当前文件中)。

ack --type=cc PySequence_Contains

接下来指向abstract.c文件中的定义(下面的返回值部分)。

result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);

然后又指向了_PySequence_IterSearch(下面的比较部分)。

cmp = PyObject_RichCompareBool(obj, item, Py_EQ);

接着指向了PyObject_RichCompareBool(这个函数也不在当前文件中)。

ack --type=cc PyObject_RichCompareBool

最后指向了object.c文件,在这里我终于找到了比较的实现,这个实现先进行身份检查,然后再进行实际的相等性检查(这正是我最初关于比较的问题)。

/* Quick result when objects are the same.
   Guarantees that identity implies equality. */
if (v == w) {
    if (op == Py_EQ)
        return 1;
    else if (op == Py_NE)
        return 0;
}
3

我觉得这个功能的实现是从 PySequence_Contains 开始的,具体在 Objects/abstract.c 这个文件里。我是通过查看 operator.contains 的实现找到的,那个实现是在 Modules/operator.c 这个文件中,它把所有Python的原生操作符封装成了函数。

撰写回答