Для Unicode и строковых типов
x in y
истинно тогда и только тогда, когда x является подстрокой [ +1134] у [+1134]. Эквивалентный тест -y.find(x) != -1
. Обратите внимание, что x и y не обязательно должны быть одного типа; следовательно,u'ab' in 'abc'
вернетTrue
. Пустые строки всегда считаются подстрокой любой другой строки, поэтому"" in "abc"
вернетTrue
.
При просмотре вызова print
вы используете 2.x.
Чтобы углубиться, посмотрим на байт-код:
>>> def answer():
... '' in 'lolsome'
>>> dis.dis(answer)
2 0 LOAD_CONST 1 ('')
3 LOAD_CONST 2 ('lolsome')
6 COMPARE_OP 6 (in)
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
COMPARE_OP
- это место, где мы выполняем нашу логическую операцию, и просмотр исходного кода для in
показывает, где сравнение происходит:
TARGET(COMPARE_OP)
{
w = POP();
v = TOP();
if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
/* INLINE: cmp(int, int) */
register long a, b;
register int res;
a = PyInt_AS_LONG(v);
b = PyInt_AS_LONG(w);
switch (oparg) {
case PyCmp_LT: res = a < b; break;
case PyCmp_LE: res = a <= b; break;
case PyCmp_EQ: res = a == b; break;
case PyCmp_NE: res = a != b; break;
case PyCmp_GT: res = a > b; break;
case PyCmp_GE: res = a >= b; break;
case PyCmp_IS: res = v == w; break;
case PyCmp_IS_NOT: res = v != w; break;
default: goto slow_compare;
}
x = res ? Py_True : Py_False;
Py_INCREF(x);
}
else {
slow_compare:
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 находится в том же файле , легко найти нашу следующую подсказку:
res = PySequence_Contains(w, v);
которая находится в ] abstract.c :
{
Py_ssize_t result;
if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
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);
}
и чтобы найти воздух из источника, мы находим следующую функцию в документации :
objobjproc PySequenceMethods.sq_contains
Эта функция может использоваться
PySequence_Contains()
и имеет такую же подпись. Этот слот можно оставить равным NULL , в этом случаеPySequence_Contains()
просто перебирает последовательность, пока не найдет совпадение.
и далее в той же документации :
int PySequence_Contains(PyObject *o, PyObject *value)
Определите, содержит ли o значение . Если элемент в o равен значению , вернуть
1
, в противном случае вернуть0
. В случае ошибки верните-1
. Это эквивалентно выражению Pythonvalue in o
.
Если ''
не является null
, можно считать, что последовательность 'lolsome'
содержит ее.
Исходный пакет PECL здесь , он должен дать вам некоторое представление о том, насколько он зрелый. И здесь - это список текущих открытых ошибок для этого пакета.
экспериментальный следует воспринимать с недоверием. Есть несколько отмеченных как таковых расширений PHP, которые довольно стабильны. Тем не менее, я не знаю, в каком состоянии находится этот конкретный пакет.
Возможно, вы захотите написать оболочку, чтобы вы могли переключаться между использованием вашего текущего подхода и использованием расширения.