Sea*_*hot 0 python iterator python-3.x
我试图__iter__在Python 3中更多地了解.出于某些原因__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
Run Code Online (Sandbox Code Playgroud)
我理解上面的代码,但是又如何使用__iter__和编写等效代码__next__()?
class Item:
def __iter__(self):
return self
#Lost here
def __next__(self,pos):
#Lost here
Run Code Online (Sandbox Code Playgroud)
我理解当python看到一个__getitem__方法时,它会尝试通过调用带有整数索引的方法来迭代该对象0.
一般来说,一个非常好的方法是通过值__iter__生成一个生成器yield.这可能不太直观,但它是直截了当的; 您只需回收所需的结果,__next__然后自动为您提供:
class Item:
def __iter__(self):
for item in range(0, 30, 10):
yield item
Run Code Online (Sandbox Code Playgroud)
这只是使用yield获得所需效果的力量,当Python调用__iter__你的对象时,它期望一个iterator(即一个支持__next__调用的对象),一个生成器就是这样,生成你的生成器函数中定义的每个项目(即__iter__在此case)何时__next__被调用:
>>> i = iter(Item())
>>> print(i) # generator, supports __next__
<generator object __iter__ at 0x7f6aeaf9e6d0>
>>> next(i)
0
>>> next(i)
10
>>> next(i)
20
Run Code Online (Sandbox Code Playgroud)
现在你得到的效果与之相同__getitem__.区别在于没有index传入,你必须手动循环它以产生结果:
>>> for i in Item():
... print(i)
0
10
20
Run Code Online (Sandbox Code Playgroud)
除此之外,还有另外两种方法可用于创建支持迭代的对象.
一次循环:使项目成为迭代器
请Item通过定义一个迭代器__next__和返回self从__iter__在这种情况下,因为你不使用yield该__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
Run Code Online (Sandbox Code Playgroud)
这也使用辅助val来从范围中获取结果并检查我们是否仍应该迭代(如果没有,我们提出StopIteration):
>>> for i in Item():
... print(i)
0
10
20
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于它是一次性骑行,在迭代一次之后,self.val点3和迭代不能再次执行.(使用yield解决此问题).(是的,你可以去设置val为0,但这只是偷偷摸摸.)
循环多次:创建自定义迭代器对象.
第二种方法是专门为您的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
Run Code Online (Sandbox Code Playgroud)
现在,每次迭代时都会提供一个新的自定义迭代器,您可以支持Item对象的多次迭代.
| 归档时间: |
|
| 查看次数: |
413 次 |
| 最近记录: |