最近遇到判斷字典中是否存在空字符串‘’,這個很好判斷,直接用:‘’ 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