在Python中,in运算符如何实现工作?它是否使用迭代器的next()方法?

时间:2018-11-29 15:53:12

标签: python

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

2 个答案:

答案 0 :(得分:2)

一个类可以通过定义in方法来定义__contains__运算符在该类实例上的工作方式。

Python data model documentation说:

  

对于未定义__contains__()的对象,成员资格测试首先尝试通过__iter__()进行迭代,然后通过__getitem__()尝试旧的序列迭代协议,请参见this section in the language reference。 / p>

Section 6.10.2, "Membership test operations", of the Python language reference这样说:

  

运算符innot in测试成员资格。如果 x s 的成员,则x in s的值为True,否则为Falsex not in s返回x in s的否定。所有内置序列和集合类型都支持此功能以及字典,为此in测试字典是否具有给定的键。对于列表,元组,集合,frozenset,字典或collections.deque等容器类型,表达式x in y等效于any(x is e or x == e for e in y)

     

对于字符串和字节类型,当且仅当 x y 的子字符串时,x in y才是True。等效测试为y.find(x) != -1。空字符串始终被认为是任何其他字符串的子字符串,因此"" in "abc"将返回True

     

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

     

对于没有定义__contains__()但定义了__iter__()的用户定义类,如果x in y中包含某个值Truezx == z }是在y上迭代时产生的。如果在迭代过程中引发了异常,就好像in引发了该异常。

     

最后,尝试使用旧式的迭代协议:如果一个类定义了__getitem__(),则当且仅当存在非负整数索引时,x in y才是True i ,使得x == y[i]和所有较低的整数索引不会引发IndexError异常。 (如果引发了任何其他异常,则好像in引发了该异常一样。)

     

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

如上所述,表达式运算符 in与构成{{3}一部分的关键字 in不同}。在Python语法中,in作为for语法的一部分被“硬编码”:

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

因此,在for语句的上下文中,in并不充当运算符,它只是将target_listexpression_list分开的语法标记。

答案 1 :(得分:1)

Python有__contains__特殊方法,您可以在进行item in collection时使用。

例如,这是一个“ __包含__”所有偶数的类:

>>> class EvenNumbers:
...   def __contains__(self, item):
...     return item % 2 == 0
...
>>> en = EvenNumbers()
>>> 2 in en
True
>>> 3 in en
False
>>>