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 文字列オブジェクトの場合、このスロットは Objects/unicodeobject.c として実装されPyUnicode_Containsます。Python 2 では、 Objects/stringobject.cstring_containsチェックアウトする必要もあります。sq_contains基本的に、さまざまな Python タイプによるさまざまな実装の Objects/ サブディレクトリをgrep するだけです。

一般的な python オブジェクトの場合、Objects/typeobject.cがこれを__contains__カスタム クラスのメソッドに任せていることに注意してください (定義されている場合)。

于 2012-09-03T08:28:32.097 に答える