最近遇到判断字典中是否存在空字符串‘’,这个很好判断,直接用:‘’ in ['a','b','c'],就能够直接判断出来;可是当我对字符串使用 “in” 方法进行判断的时候,发现:‘’ in ‘abc' 仍然会返回True,对于这个问题,以前一直没有注意到过其中的原理,如今去进行探索总结一下:html
首先,查看官方文档:https://docs.python.org/2/reference/expressions.html#not-inpython
文档在5.9.2中:Membership test operations中是以下说明的:express
大概翻译一下意思就是说: 函数
“in” 和 “not in” 是对集合成员的检测操做,若是 x 在 集合s 中的话那么 x in s 返回True,不然返回False。x not in s 跟 x in s 判断是相反的。 成员的检测被绑定到序列;若是集合是序列,而且包含与该对象相等的元素,则对象是集合的成员。然而,对于许多其余对象类型来讲,即便不是序列,可是支持成员测试也是有意义的。特别是,dict(key) 和 sets 支持成员资格测试。测试
在版本2.3的时候被改变了:以前的版本,’x‘ 被要求是长度为 1 的字符串。spa
“not in” 操做和 “in” 操做产生的结果相反翻译
看完官方文档后,对于判断“String”类型的时候,能够经过 y.find(x) != -1 来测试其是否成立,可是这个原理是怎么来的,仍是想进一步进行探究,下面查看Python2.7的源码:code
首先,猜想在源码中首先应该和对象类型有关系,而后找到发现有typeobject.c文件,浏览后发现,含有以下代码:htm
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, "x.__contains__(y) <==> y in x"),
而后接下来推测去找跟__contains__方法有关的和 上面说到的 find() 方法有关的源码:对象
Py_LOCAL_INLINE(int) stringlib_contains_obj(PyObject* str, PyObject* sub) { return stringlib_find( STRINGLIB_STR(str), STRINGLIB_LEN(str), STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0 ) != -1; }
Py_LOCAL_INLINE(Py_ssize_t) stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, Py_ssize_t offset) { Py_ssize_t pos; if (str_len < 0) return -1; if (sub_len == 0) return offset; pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_SEARCH); if (pos >= 0) pos += offset; return pos; }
由于源码关联性的缘由,接下来能够在 stringobject.c 文件中,结合 find.h 进行对于其返回值的原理查看,这里就不一一列出来了。
源码目录:
Objects/Stringlib/find.h
Objects/typeobject.c
Objects/stringobject.c