首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在类上定义__getitem__使得它在python中是可迭代的?

为什么在类上定义__getitem__使得它在python中是可迭代的?
EN

Stack Overflow用户
提问于 2009-05-29 15:22:53
回答 6查看 30K关注 0票数 73

为什么在类上定义__getitem__会让它变得可迭代?

例如,如果我写道:

代码语言:javascript
运行
复制
class b:
  def __getitem__(self, k):
    return k

cb = b()

for k in cb:
  print k

我得到了输出:

代码语言:javascript
运行
复制
0
1
2
3
4
5
6
7
8
...

我真的希望看到"for k in cb:“返回一个错误。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-05-29 15:29:22

如果你看一下定义迭代器的PEP234,它会说:

代码语言:javascript
运行
复制
1. An object can be iterated over with "for" if it implements
   __iter__() or __getitem__().

2. An object can function as an iterator if it implements next().
票数 54
EN

Stack Overflow用户

发布于 2009-05-29 15:37:35

迭代对__getitem__的支持可以看作是一个“遗留特性”,当PEP234引入可迭代性作为主要概念时,它允许更平滑的过渡。它只适用于没有__iter__的类,这些类的__getitem__接受整数0、1和c,一旦索引变得太高(如果有的话),就会引发IndexError,通常是在__iter__出现之前编码的“序列”类(尽管没有什么可以阻止您以这种方式编写新类)。

就我个人而言,我不希望在新代码中依赖它,尽管它没有被弃用,也不会消失(在Python3中也可以很好地工作),所以这只是一个风格和品味问题(“显式比隐式好”,所以我宁愿显式地支持可迭代性,而不是依赖__getitem__对它的隐式支持--但不是很重要)。

票数 73
EN

Stack Overflow用户

发布于 2009-05-29 15:38:10

__getitem__早于迭代器协议,并且在过去是使事物可迭代的唯一方法。因此,它仍然被支持作为一种迭代方法。本质上,迭代的协议是:

  1. 检查__iter__方法。如果存在,请使用新的迭代protocol.
  2. Otherwise,尝试使用连续更大的整数值调用__getitem__,直到它引发IndexError。

(2)曾经是做这件事的唯一方法,但它的缺点是它假设了比支持迭代所需的更多的东西。为了支持迭代,你必须支持随机访问,这对于像文件或网络流这样的东西来说要昂贵得多,因为向前走很容易,但向后走需要存储所有东西。__iter__允许在没有随机访问的情况下进行迭代,但由于随机访问通常允许迭代,而且打破向后兼容性会很糟糕,因此仍然支持__getitem__

票数 39
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/926574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档