14

in我试图在 (C) Python 源代码中找到内置运算符的实现。我搜索了内置函数源代码bltinmodule.c,但找不到该运算符的实现。我在哪里可以找到这个实现?

我的目标是通过扩展此搜索的不同 C 实现来改进 Python 中的子字符串搜索,尽管我不确定 Python 是否已经使用了我的想法。

4

2 回答 2

41

要查找任何python 运算符的实现,首先要使用以下dis.dis函数找出 Python 为其生成的字节码:

>>> dis.dis("'0' in ()")
  1           0 LOAD_CONST               0 ('0')
              2 LOAD_CONST               1 (())
              4 COMPARE_OP               6 (in)
              6 RETURN_VALUE

in运算符变成一个COMPARE_OP字节码。现在,您可以在 Python 评估循环中跟踪此操作码是如何被处理的Python/ceval.c

TARGET(COMPARE_OP)
    PyObject *right = POP();
    PyObject *left = TOP();
    PyObject *res = cmp_outcome(oparg, left, right);
    Py_DECREF(left);
    Py_DECREF(right);
    SET_TOP(res);
    if (res == NULL)
        goto error;
    PREDICT(POP_JUMP_IF_FALSE);
    PREDICT(POP_JUMP_IF_TRUE);
    DISPATCH();

cmp_outcome()在同一个文件中定义,in操作符是开关之一:

case PyCmp_IN:
    res = PySequence_Contains(w, v);
    if (res < 0)
         return NULL;
    break;

快速 grep 向我们展示了在Objects/abstract.cPySequence_Contains中定义的位置:

int
PySequence_Contains(PyObject *seq, PyObject *ob)
{
    Py_ssize_t result;
    PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
    if (sqm != NULL && sqm->sq_contains != NULL)
        return (*sqm->sq_contains)(seq, ob);
    result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
    return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
}

PySequence_Contains因此,对于 Python C 对象,使用sq_containsSequence 对象结构上的插槽或迭代搜索。

对于 Python 3 Unicode 字符串对象,此插槽PyUnicode_Contains在 Objects/unicodeobject.c中实现,在 Python 2 中,您还想string_contains在 Objects/stringobject.c中签出。基本上只是在 Objects/ 子目录中 grep forsq_contains不同 Python 类型的各种实现。

对于泛型 python 对象,有趣的是Objects/typeobject.c将此推迟到__contains__自定义类上的方法,如果这样定义的话。

于 2012-09-03T08:28:32.097 回答
0

在 python 3.9 中,字节码COMPARE_OP被分成四个不同的指令,CONTAINS_OP用于 'in' 和 'not in' 测试。

这并没有改变inoperator 的实现,它直接在Python/ceval.c中处理,调用PySequence_Contains().

于 2022-03-01T06:19:47.350 回答