首页 > 解决方案 > 在 Python 中,in 运算符是如何实现的?它是否使用迭代器的 next() 方法?

问题描述

在 Python 中,已知in检查迭代器(列表、字典等)中的成员资格并在字符串中查找子字符串。我的问题是关于如何实现in以实现以下所有功能:1)测试成员资格,2)测试子字符串和 3)访问 for 循环中的下一个元素。例如,当for i in myList:orif i in myList:被执行时,in call myList.__next__()? 如果它确实调用了它,那么它如何处理字符串,因为str对象不是迭代器(如在 Python 2.7 中检查的那样),因此没有next()方法?如果无法详细讨论in的实现,请在此处提供其要点。

标签: pythonin-operator

解决方案


一个类可以通过定义一个方法来定义in操作符如何处理该类的实例。__contains__

Python 数据模型文档说:

对于未定义__contains__()的对象,成员资格测试首先尝试迭代 via __iter__(),然后是旧的序列迭代协议 via __getitem__(),请参阅语言参考中的这一部分

Python 语言参考的第 6.10.2 节“成员资格测试操作”有这样的说法:

运算符innot in成员资格测试。如果xsx in s的成员,则计算结果,否则。返回 的否定。所有内置序列和集合类型都支持这一点以及字典,用于测试字典是否具有给定键。对于 list、tuple、set、frozenset、dict 或 collections.deque 等容器类型,表达式等效于.TrueFalsex not in sx in sinx in yany(x is e or x == e for e in y)

对于 string 和 bytes 类型,当且仅当xx in yy的子字符串时。一个等效的测试是。空字符串总是被认为是任何其他字符串的子字符串,所以会返回。Truey.find(x) != -1"" in "abc"True

对于定义__contains__()方法的用户定义类,如果x in y返回真值则返回,否则返回。Truey.__contains__(x)False

对于没有定义__contains__()但确实定义的用户定义的类__iter__()x in y是如果在迭代时产生了一些True值。如果在迭代过程中引发异常,就好像引发了该异常。zx == zyin

最后,尝试了旧式迭代协议:如果一个类定义了__getitem__(),当且x in yTrue当存在一个非负整数索引i满足x == y[i],并且所有较低整数索引都不会引发IndexError异常时。(如果引发任何其他异常,则如同in引发该异常)。

运算符not in被定义为具有 的反真值in

正如上面的注释所示,表达式运算符与构成 语句一部分关键字in不同。在 Python 语法中,被“硬编码”为语法的一部分: inforinfor

for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

for因此,在语句的上下文中,in它不表现为运算符,它只是将 . 与 . 分开的句法target_list标记expression_list


推荐阅读