python - 在 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的实现,请在此处提供其要点。
解决方案
一个类可以通过定义一个方法来定义in
操作符如何处理该类的实例。__contains__
对于未定义
__contains__()
的对象,成员资格测试首先尝试迭代 via__iter__()
,然后是旧的序列迭代协议 via__getitem__()
,请参阅语言参考中的这一部分。
Python 语言参考的第 6.10.2 节“成员资格测试操作”有这样的说法:
运算符
in
和not in
成员资格测试。如果x是sx in s
的成员,则计算结果,否则。返回 的否定。所有内置序列和集合类型都支持这一点以及字典,用于测试字典是否具有给定键。对于 list、tuple、set、frozenset、dict 或 collections.deque 等容器类型,表达式等效于.True
False
x not in s
x in s
in
x in y
any(x is e or x == e for e in y)
对于 string 和 bytes 类型,当且仅当x
x in y
是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
不同。在 Python 语法中,被“硬编码”为语法的一部分: in
for
in
for
for_stmt ::= "for" target_list "in" expression_list ":" suite ["else" ":" suite]
for
因此,在语句的上下文中,in
它不表现为运算符,它只是将 . 与 . 分开的句法target_list
标记expression_list
。
推荐阅读
- symfony - Symfony,如何显示对象的正常名称而不是实体编号
- typescript - 转译后访问 TypeScript 中已声明(而非导出)模块中的枚举
- angular - Angular Build Breaks with provider.ngOnDestroy
- angular - Angular 6 设置指令
- python - 类实例的 Python 相等性
- java - 都指定时找不到 persistence.xml 和提供程序
- mysql - MariaDB 复制挂起,没有任何错误
- arm - 在 STM32L1x 中进入 STOP 模式之前禁用所有中断挂起位
- excel - Excel 按钮 VBA 在 64 位 Excel 2016 中不起作用
- vue.js - JS文件中的VSCode黄色HTML