- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
为什么要有一个 __iter__
方法?如果一个对象是一个迭代器,那么拥有一个返回自身的方法是没有意义的。如果它不是迭代器而是可迭代的,即带有 __iter__
和 __getitem__
方法的东西,那么为什么要定义返回迭代器但不是迭代器本身?在 Python 中,什么时候会想要定义一个本身不是迭代器的可迭代对象?或者,什么是可迭代但不是迭代器的示例?
最佳答案
尝试一次回答一个问题:
Why have an
__iter__
method? If an object is an iterator, then it is pointless to have a method which returns itself.
这不是没有意义的。迭代器协议(protocol)需要 __iter__
和 __next__
(或 Python 2 中的 next
)方法。我见过的所有理智的迭代器都只是在它们的 __iter__
方法中 return self
,但拥有该方法仍然至关重要。没有它会导致各种怪异,例如:
somelist = [1, 2, 3]
it = iter(somelist)
现在
iter(it)
或
for x in it: pass
会抛出一个 TypeError
并提示 it
不可迭代,因为当 iter(x)
被调用时(这隐含地发生在你使用一个 for
循环)它期望参数对象 x
能够产生一个迭代器(它只是试图在该对象上调用 __iter__
) .具体示例(Python 3):
>>> class A:
... def __iter__(self):
... return B()
...
>>> class B:
... def __next__(self):
... pass
...
>>> iter(iter(A()))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'B' object is not iterable
考虑任何函数,特别是来自 itertools 的函数期望一个可迭代的,例如 dropwhile .使用任何具有 __iter__
方法的对象调用它都可以,无论它是不是迭代器的可迭代对象还是迭代器 - 因为调用 iter 时您可以期待相同的结果
以该对象作为参数。在这里对两种可迭代对象进行奇怪的区分会违背 python 强烈支持的鸭子类型原则。
像这样的巧妙技巧
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(zip(*[iter(a)]*3))
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
如果您不能将迭代器传递给 zip
,就会停止工作。
why would one want to ever define something which returns an iterator but is not an iterator itself
让我们考虑一下这个简单的列表迭代器:
>>> class MyList(list):
... def __iter__(self):
... return MyListIterator(self)
>>>
>>> class MyListIterator:
... def __init__(self, lst):
... self._lst = lst
... self.index = 0
... def __iter__(self):
... return self
... def __next__(self):
... try:
... n = self._lst[self.index]
... self.index += 1
... return n
... except IndexError:
... raise StopIteration
>>>
>>> a = MyList([1,2,3])
>>> for x in a:
... for x in a:
... x
...
1
2
3
1
2
3
1
2
3
请记住,对于两个 for
循环,iter
都是通过相关的可迭代对象调用的,每次从对象的 中期望一个新 迭代器>__iter__
方法。
现在,如果每次使用 for
循环时都不会生成迭代器,当 MyList
时,您如何能够跟踪任何迭代的当前状态对象同时迭代任意次数?哦,是的,你不能。 :)
编辑:奖金和对 Tadhg McDonald-Jensen 评论的回复
可重用迭代器并非不可想象,但当然有点奇怪,因为它依赖于使用“非消耗性”迭代器(即不是经典迭代器)进行初始化:
>>> class riter(object):
... def __init__(self, iterable):
... self.iterable = iterable
... self.it = iter(iterable)
... def __next__(self): # python 2: next
... try:
... return next(self.it)
... except StopIteration:
... self.it = iter(self.iterable)
... raise
... def __iter__(self):
... return self
...
>>>
>>> a = [1, 2, 3]
>>> it = riter(a)
>>> for x in it:
... x
...
1
2
3
>>> for x in it:
... x
...
1
2
3
关于python - 为什么在 Python 中有一个 __iter__ 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36681312/
我正在实现本质上是一个容器对象(尽管它确实有一些自己的逻辑)。我希望能够迭代此类(这只是一个普通列表)中的一个字段中的项目。我应该为我的类(class)重新实现 __iter__ 和 next 还是可
本人python水平很差,请不要打我。 >>> a = ['a', 'b', 'c'] >>> a.__iter__() >>> a.__iter__().__iter__() 我看到这两个 li
在 python 2.7 和 python 3.7 中,我可以执行以下操作: string = "hello world" for letter in string: print(letter
假设我有一个基类: class Base: A = False B = '' C = '' def __iter__(self): yield 'a',
Python 类定义中的 __iter__ 方法主体有何意义?据我了解, __iter__ 方法必须返回一个迭代器;那么每个 __iter__ 方法不应该只包含一个返回迭代器(在其他地方定义)的 re
我正在尝试创建一个二维数组类并希望使矩阵可迭代。有谁知道该怎么做?我是 python 类(class)的新手,但仍在掌握窍门。另外,如何在我的 main 中实现 str ?如果我只使用 print(c
我读了一本有关 Python 高级主题的书。作者试图解释生成器。 这是他要解释的例子: class rev: def __init__(self,data): self.dat
不确定标题是否清楚,但我有一个对象,它的属性是另一种对象的字典。键是引用对象的 id。我想实现 iter 方法,以便生成这些 key ,但我不确定如何操作。它应该相当简单,但我在 python 文档中
def __init__(self, maximum, start=0, step=1): """Sets the maximum, start, and step"""
我想做的是重用生成器 class Rect(object): ... def __iter__(self): for y in xrange(self.tl.y, self.
使用__iter__有什么好处? Python 类中的函数? 在下面的代码中,我只是设置两个简单的类。第一类接受一个列表作为参数,我可以在不使用 __iter__ 的情况下循环这个列表。功能。第二位代
我不明白为什么 __iter__ 特殊方法只返回调用它的对象(如果它是在迭代器上调用的)。它本质上只是一个标志,表明该对象是一个迭代器吗? 编辑:实际上,我发现“这是允许容器和迭代器与 for 和 i
我有一个对象子类,它使用缓存生成器实现动态调度 __ iter __(我还有一个使 iter 缓存无效的方法),如下所示: def __iter__(self): print("iter ca
尽管阅读了它,但我仍然不太明白 __iter__ 是如何工作的。什么是简单的解释? 我见过 def__iter__(self): return self。我看不到它是如何工作的,也不知道它是如何工作的
我正在实现搜索算法 (BFS) 并具有以下 Node 类: class Node: def __init__(self, state=None, action=None, path_cost=
我有一个 Python 2.7 类(称之为 Child),它是另一个类(Parent)的子类,而另一个类本身就是 dict 的子类。 我正在尝试定义 __iter__在 child 中希望当有人做di
我想将一个类的所有实例存储在一个列表中,并想对其进行迭代。 我尝试了以下两种方法: 1 使用元类 class ClassIter(type): def __iter__(cls):
来源 def flags(*opts): keys = [t[0] for t in opts] words = [t[1] for t in opts] nums = [2*
假设您使用包装器对象: class IterOrNotIter: def __init__(self): self.f = open('/tmp/toto.txt')
我有一个标准的二叉树,如下所示 1 /\ 2 3 /\/\ 4 5 6 7 我需要通过导入我的树类来读取二叉树,创建这棵树,然后使用 for 循环读取它,如:[4, 2, 5, 1, 6, 3, 7]
我是一名优秀的程序员,十分优秀!