对我来说,这发生在 Python 2.7.6 和 3.3.3 中。当我这样定义一个类时
class foo:
def __getitem__(self, *args):
print(*args)
然后尝试在一个实例上迭代(以及我认为称为 iter 的东西),
bar = foo()
for i in bar:
print(i)
它只是将 args 加一并永远打印 None 。就语言设计而言,这是故意的吗?
示例输出
0
None
1
None
2
None
3
None
4
None
5
None
6
None
7
None
8
None
9
None
10
None
原文由 wegry 发布,翻译遵循 CC BY-SA 4.0 许可协议
是的,这是有意设计的。它被记录在案、经过良好测试,并被诸如 str 之类的序列类型所依赖。
getitem 版本是 Python 拥有现代迭代器之前的遗产。这个想法是任何序列(可索引且具有长度的东西)都可以使用系列 s[0]、s[1]、s[2]、… 自动迭代,直到引发 IndexError 或 StopIteration 。
例如,在 Python 2.7 中,由于 getitem 方法( str 类型没有 iter 方法),字符串是可迭代的。
相反,迭代器协议让任何类都可以迭代,而不必是可索引的(例如字典和集合)。
以下是如何使用序列的遗留样式创建可迭代类:
以下是使用 iter 方法创建可迭代对象的方法:
对细节感兴趣的朋友,相关代码在Objects/iterobject.c中:
在 Objects/abstract.c 中: