内置“in”运算符的Python源代码
我试图在(C)Python源代码中找到内置运算符的实现。 我在内置函数源代码bltinmodule.c中搜索过 ,但是找不到这个运算符的实现。 我在哪里可以找到这个实现?
我的目标是通过扩展此搜索的不同C实现来改进Python中的子字符串搜索,尽管我不确定Python是否已经使用了我的想法。
要查找任何 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/ceval.c
的Python评估循环中跟踪如何处理此操作码:
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.c中定义PySequence_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); }
因此,对于Python C对象, PySequence_Contains
使用Sequence对象结构上的sq_contains
槽或否则使用迭代搜索。
对于Python 3 Unicode字符串对象,此插槽在Objects / unicodeobject.c中实现为PyUnicode_Contains
,在Python 2中,您还要查看Objects / stringobject.c中的string_contains 。 基本上只是grep for Objects /子目录中的sq_contains
,用于不同Python类型的各种实现。
对于通用python对象,有趣的是注意到Objects / typeobject.c将其推迟到自定义类的__contains__
方法,如果这样定义的话。