为什么在类上定义uu getitem uuu会使它在python中变得可移植?

为什么在类上定义uu getitem uuu会使它在python中变得可移植?,python,iterator,overloading,Python,Iterator,Overloading,为什么在类上定义u_getitem_u___)会使它变得不可访问 例如,如果我写: class b: def __getitem__(self, k): return k cb = b() for k in cb: print k 我得到输出: 0 1 2 3 4 5 6 7 8 ... 我真的希望看到从“for k in cb:”返回的错误,因为cb[0]与cb相同。请参见此部分的。特殊方法,例如\uuu getitem\uuu向对象添加特殊行为,包括迭代 “for循

为什么在类上定义u_getitem_u___)会使它变得不可访问

例如,如果我写:

class b:
  def __getitem__(self, k):
    return k

cb = b()

for k in cb:
  print k
我得到输出:

0
1
2
3
4
5
6
7
8
...

我真的希望看到从“for k in cb:”

返回的错误,因为
cb[0]
cb相同。请参见此部分的。

特殊方法,例如
\uuu getitem\uuu
向对象添加特殊行为,包括迭代

“for循环期望针对非法索引引发索引器,以允许正确检测序列的结尾。”

升起索引器以发出序列结束的信号

您的代码基本上等同于:

i = 0
while True:
    try:
        yield object[i]
        i += 1
    except IndexError:
        break
Where object是您在for循环中迭代的对象。

如果您看一下定义迭代器,它会说:

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().

迭代对
\uuuu getitem\uuuu
的支持可以被看作是一种“遗留功能”,当PEP234将可移植性作为一个主要概念引入时,它允许更平滑的过渡。它只适用于没有
\uuu iter\uuuu
的类,这些类的
\uuu getitem\uuuu
接受整数0、1和c,并在索引过高(如果有)时引发
索引器,通常在出现
\uuu iter\uuuu
之前对类进行“排序”(尽管没有任何东西阻止您以这种方式编码新类)


就我个人而言,我不希望在新代码中依赖它,尽管它没有被弃用,也不会消失(在Python 3中也很好),所以这只是风格和品味的问题(“显式优于隐式”因此,我宁愿显式地支持可移植性,而不是依赖于
\uuu getitem\uuuu
为我隐式地支持它——但是,这不是一个大问题)。

\uu getitem\uuuuu
早于迭代器协议,过去是使事情可移植的唯一方法。因此,它仍然作为一种迭代方法受到支持。本质上,迭代的协议是:

  • 检查有无
    \uuuuuuuuuuuuuuuuuuuu
    方法。如果存在,则使用新的迭代协议

  • 否则,请尝试使用连续较大的整数值调用
    \uuuu getitem\uuuu
    ,直到它引发Indexer错误


  • (2) 曾经是实现这一点的唯一方法,但有一个缺点,即它假设的内容超过了支持迭代所需的内容。为了支持迭代,您必须支持随机访问,这对于文件或网络流之类的东西来说要昂贵得多,因为前进很容易,但后退需要存储所有内容<代码>\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。在Python 2.2之前,getitem是创建可以使用for循环迭代的类的唯一方法。在2.2中添加了uuu iter uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?从阅读答案中,我觉得如果您想要
    []
    属性访问和一个iterable,那么您不能仅使用
    \uuuu getitem\uuuu
    。然后,您应该使用
    \uuuuuuu getitem\uuuuuuuuuuu
    进行
    []
    访问,使用
    \uuuuuuuu iter\uuuuuuuuuuu
    进行迭代器,对吗?与
    \uuuuu getitem\uuuuuuuuuuuuuu
    相反的另一点是,任何整数类型都有一个上限,因此索引访问可能会遇到这个问题。然而,
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu下一步
    可以无限快乐地继续前进。(至少,这是我的理解。)注意到pythons int没有限制。这是一个任意大小的整数。是的,谢谢,这回答了我的问题:“如果它没有损坏,为什么要修复它?”。