Para encontrar la aplicación de cualquier operador de pitón, primero averiguar qué código de bytes Python genera para ello, utilizando la 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
El operador in
se convierte en un código de bytes COMPARE_OP
. Ahora se puede rastrear esta en el circuito de evaluación en 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()
se define en el mismo archivo, y el operador in
es uno de los interruptores:
case PyCmp_IN:
res = PySequence_Contains(w, v);
if (res < 0)
return NULL;
break;
Un grep rápido nos donde muestra PySequence_Contains
se define, en 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
por lo tanto utiliza el sq_contains
slot on the Sequence object structure o una búsqueda iterativa de lo contrario, para objetos C de Python.
Para los objetos de cadena Unicode de python 3, esta ranura se implementa como PyUnicode_Contains
in Objects/unicodeobject.c, en Python 2 también desea ver string_contains
in Objects/stringobject.c. Básicamente grep para sq_contains
en el subdirectorio Objects/para las diversas implementaciones por los diferentes tipos de Python.
Para objetos genéricos de pitón, es interesante observar que Objects/typeobject.c lo difiere al método __contains__
en clases personalizadas, si así se define.
Gracias por su respuesta – Michael
@Michael: por favor, considere aceptar esta respuesta ya que es mucho más útil que la mía. – georg
@ thg435: tiene razón, +1 la respuesta ha sido aceptada – Michael