2012-09-03 8 views
9

Próbuję znaleźć implementację wbudowanego operatora in w kodzie źródłowym (C) Pythona. Przeszukałem wbudowany kod źródłowy funkcji, bltinmodule.c, ale nie mogę znaleźć implementacji tego operatora. Gdzie mogę znaleźć tę implementację?Kod źródłowy Pythona dla wbudowanego operatora "in"

Moim celem jest ulepszenie wyszukiwania pod-ciągów w Pythonie poprzez rozszerzenie różnych implementacji C tego wyszukiwania, chociaż nie jestem pewien, czy Python już używa mojego pomysłu.

Odpowiedz

30

Aby znaleźć realizację dowolny operatora Pythona, najpierw dowiedzieć się, jakie kodu bajtowego Python generuje dla niej, używając dis.dis function:

>>> def inop(): 
...  '0' in [] 
... 
>>> dis.dis(inop) 
    2   0 LOAD_CONST    1 ('0') 
       3 LOAD_CONST    2 (()) 
       6 COMPARE_OP    6 (in) 
       9 POP_TOP    
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   

Operator in staje się kod COMPARE_OP bajt. Teraz można śledzić to w pętli oceny w Python/ceval.c:

TARGET(COMPARE_OP) 
    w = POP(); 
    v = TOP(); 
    x = cmp_outcome(oparg, v, w); 
    Py_DECREF(v); 
    Py_DECREF(w); 
    SET_TOP(x); 
    if (x == NULL) break; 
    PREDICT(POP_JUMP_IF_FALSE); 
    PREDICT(POP_JUMP_IF_TRUE); 
    DISPATCH(); 

cmp_outcome() jest zdefiniowana w tym samym pliku, a operator in jest jeden z przełączników:

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

Szybkie grep pokazuje nam, gdzie PySequence_Contains został zdefiniowany w Objects/abstract.c:

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 sposób wykorzystuje sq_contains slot on the Sequence object structure lub wyszukiwanie iteracyjne w przypadku obiektów Python C.

Dla obiektów napisanych w python 3 unicode, ten slot jest zaimplementowany jako PyUnicode_Contains in Objects/unicodeobject.c, w Pythonie 2 również chcesz sprawdzić string_contains in Objects/stringobject.c. Zasadniczo po prostu grep dla sq_contains w podkatalogu Obiekty/podkatalogu dla różnych implementacji według różnych typów Pythona.

Dla ogólnych obiektów python warto zauważyć, że Objects/typeobject.c odrzuca to do metody __contains__ na niestandardowych klasach, jeśli tak zdefiniowano.

+0

Dzięki za odpowiedź – Michael

+2

@Michael: rozważ zaakceptowanie tej odpowiedzi, ponieważ jest ona o wiele bardziej pomocna niż moja. – georg

+0

@ thg435: masz rację, +1 odpowiedź została przyjęta – Michael