__iter__中__getitem__的等效代码

时间:2016-08-03 07:17:03

标签: python python-3.x iterator

我想了解更多有关Python 3中的__iter__的信息。出于某些原因,我__getitem____iter__更了解__iter__。我想我不知道如何获得相应的下一个实施,然后是class Item: def __getitem__(self,pos): return range(0,30,10)[pos] item1= Item() print (f[1]) # 10 for i in item1: print (i) # 0 10 20

我有以下代码:

__iter__

我理解上面的代码,但是我又如何使用__next__()class Item: def __iter__(self): return self #Lost here def __next__(self,pos): #Lost here 编写等效代码?

__getitem__

我理解当python看到0方法时,它会尝试通过使用以flag = 0 processName := "xenia.exe" Loop { If ProcessExist(processName) { WinGetTitle, title, ahk_exe %processName% IfWinActive, %title% { if flag = 0 { Send, {F11} flag = 1 } } else { flag = 0 } } Sleep, 1000 } ProcessExist(Name) { Process,Exist,%Name% return Errorlevel } 开头的整数索引调用该方法来迭代该对象。

2 个答案:

答案 0 :(得分:5)

一般来说,一个非常好的方法是通过__iter__值使yield成为生成器。这可能 less 直观,但它是直截了当的;您只需返回所需的结果,然后会自动为您提供__next__

class Item:
   def __iter__(self):
      for item in range(0, 30, 10):
          yield item

这只是使用yield的强大功能来获得所需的效果,当Python调用对象上的__iter__时,它会期望返回iterator(即支持__next__调用),生成器就是这样做的,在调用__iter__时生成生成器函数中定义的每个项目(在本例中为__next__):

>>> i = iter(Item())    
>>> print(i)  # generator, supports __next__
<generator object __iter__ at 0x7f6aeaf9e6d0>
>>> next(i)
0
>>> next(i)
10
>>> next(i)
20

现在,您获得与__getitem__相同的效果。区别在于没有传递index,您必须手动循环才能产生结果:

>>> for i in Item():
...    print(i)    
0
10
20

除此之外,还有另外两种方法可用于创建支持迭代的对象。

一次循环:将项目设为迭代器

通过定义Item并在这种情况下从__next__返回self来使__iter__成为迭代器,因为您没有使用yield {{1} }}方法返回__iter__self处理返回值的逻辑:

__next__

这也使用辅助class Item: def __init__(self): self.val = 0 def __iter__(self): return self def __next__(self): if self.val > 2: raise StopIteration res = range(0, 30, 10)[self.val] self.val += 1 return res 从范围中获取结果,并检查我们是否仍应迭代(如果没有,我们引发val):

StopIteration

这种方法的问题在于它是一次性的,在迭代一次之后,>>> for i in Item(): ... print(i) 0 10 20 指向self.val并且不能再次执行迭代。 (使用3解决了这个问题)。 (是的,您可以将yield设置为0但这只是偷偷摸摸的。)

多次循环:创建自定义迭代器对象。

第二种方法是专门为val类使用自定义迭代器对象,并从Item而不是Item.__iter__返回:

self

现在每次迭代时都会提供一个新的自定义迭代器,你可以支持class Item: def __iter__(self): return IterItem() class IterItem: def __init__(self): self.val = 0 def __iter__(self): return self def __next__(self): if self.val > 2: raise StopIteration res = range(0, 30, 10)[self.val] self.val += 1 return res 个对象的多次迭代。

答案 1 :(得分:0)

Iter返回一个迭代器,主要是@machineyearning在评论中告诉的生成器,接下来你可以遍历该对象,参见示例:

class Item:
    def __init__(self):
        self.elems   = range(10)
        self.current = 0

    def __iter__(self):
        return (x for x in self.elems)

    def __next__(self):
        if self.current >= len(self.elems):
            self.current = 0
            raise StopIteration
        return self.elems[self.current]

>>> i = Item()
>>> a = iter(i)
>>> for x in a:
...     print x
...     
0
1
2
3
4
5
6
7
8
9
>>> for x in i:
...     print x
...     
0
1
2
3
4
5
6
7
8
9