在Python中,众所周知, in 在迭代器(列表,字典等)中检查成员资格,并在字符串中查找子字符串。我的问题是关于如何实现 in 来实现以下所有功能:1)测试成员资格,2)测试子字符串,以及3)访问for循环中的下一个元素。例如,当执行for i in myList:
或if i in myList:
时, in 是否调用myList.__next__()
?如果确实调用了它,那么它会如何处理字符串,因为 str 对象不是迭代器(如python 2.7中所述),因此没有 next()方法?如果无法详细讨论 in 的实现,请在此处提供其要旨。谢谢!
答案 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这样说:
运算符
in
和not in
测试成员资格。如果 x 是 s 的成员,则x in s
的值为True
,否则为False
。x 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
中包含某个值True
,z
为x == 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_list
与expression_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
>>>