我有限的大脑无法理解为什么会这样:
>>> print '' in 'lolsome' True
在PHP中,等效比较返回false:
var_dump(strpos('', 'lolsome'));
从文档中:
对于Unicode和字符串类型,x in y当且仅当 x 是 y 的子字符串时,才为true 。等效测试为y.find(x) != -1。注意, x 和 y 不必是同一类型;因此,u'ab' in 'abc'将返回True。 空字符串始终被视为任何其他字符串的子字符串,因此"" in "abc"将返回True。
x in y
y.find(x) != -1
u'ab' in 'abc'
True
"" in "abc"
通过查看print呼叫,您正在使用2.x。
print
要更深入,请看一下字节码:
>>> 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揭示比较发生位置的地方:
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()仅遍历序列,直到找到匹配项为止。
objobjproc PySequenceMethods.sq_contains
此功能可能由PySequence_Contains()相同的签名使用。该插槽可以保留为 NULL ,在这种情况下,PySequence_Contains()仅遍历序列,直到找到匹配项为止。
PySequence_Contains()
并在同一文档中进一步介绍:
int PySequence_Contains(PyObject *o, PyObject *value) 确定 o是否 包含 值 。如果 o中 的项等于 value ,则返回1,否则返回0。出错时,返回-1。这等效于Python表达式value in o。
int PySequence_Contains(PyObject *o, PyObject *value)
确定 o是否 包含 值 。如果 o中 的项等于 value ,则返回1,否则返回0。出错时,返回-1。这等效于Python表达式value in o。
1
0
-1
value in o
如果''不是null,则'lolsome'可以认为该序列包含该序列。
''
null
'lolsome'