2012-09-03 14 views
9

Sto cercando di trovare l'implementazione dell'operatore in integrato nel codice sorgente (C) Python. Ho cercato nel codice sorgente delle funzioni integrate, bltinmodule.c, ma non riesco a trovare l'implementazione di questo operatore. Dove posso trovare questa implementazione?Codice sorgente Python per operatore "in" incorporato

Il mio obiettivo è migliorare la ricerca di sottostringa in Python estendendo diverse implementazioni C di questa ricerca, anche se non sono sicuro che Python usi già l'idea che ho.

risposta

30

Per trovare l'attuazione di qualsiasi operatore di pitone, prima scoprire che cosa bytecode Python genera per esso, utilizzando il 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   

L'operatore in diventa un codice COMPARE_OP di byte. Ora è possibile rintracciare questo nel ciclo di valutazione in 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() è definito nello stesso file, e l'operatore in è uno degli interruttori:

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

Un grep rapido noi dove mostra PySequence_Contains è definito, in 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 utilizza quindi il sq_contains slot on the Sequence object structure o una ricerca iterativa in caso contrario, per oggetti Python C.

Per gli oggetti stringa unicode python 3, questo slot è implementato come PyUnicode_Contains in Objects/unicodeobject.c, in Python 2 si desidera anche verificare string_contains in Objects/stringobject.c. Fondamentalmente solo grep per sq_contains nella sottodirectory Oggetti/per le varie implementazioni dai diversi tipi Python.

Per oggetti Python generici, è interessante notare che Objects/typeobject.c lo rimandano al metodo __contains__ su classi personalizzate, se così definito.

+0

Grazie per la risposta – Michael

+2

@ Michael: per favore considera di accettare questa risposta in quanto è molto più utile della mia. – georg

+0

@ thg435: hai ragione, +1 la risposta è stata accettata – Michael