Python 为循环中断清理

Python 为循环中断清理,python,python-3.x,for-loop,iterator,iterable,Python,Python 3.x,For Loop,Iterator,Iterable,能否在python中创建一个iterable,在for循环退出时运行清理代码?比如: from random import randint class Iterable: def __iter__(self): return self def __next__(self): return randint(1, 10) def __iterclose__(self): print("Clean up code") for

能否在python中创建一个iterable,在for循环退出时运行清理代码?比如:

from random import randint

class Iterable:
    def __iter__(self):
        return self
    def __next__(self):
        return randint(1, 10)
    def __iterclose__(self):
        print("Clean up code")

for x in Iterable():
    if x < 5:
        break

# Prints "Clean up code"
来自随机导入randint
类Iterable:
定义(自我):
回归自我
定义下一个(自我):
返回randint(1,10)
def __; iterclose ___;(自身):
打印(“清理代码”)
对于Iterable()中的x:
如果x<5:
打破
#打印“清理代码”

我认为为了从iterable协议中获益,您应该让您的iterable获得对停止条件的控制。这个怎么样:


从随机导入randint
类Iterable:
定义初始值(自身,最大值):
self.i=0
self.max=max
定义(自我):
回归自我
定义下一个(自我):
self.i+=1
如果self.i>self.max:
self.cleanup()
提出停止迭代
返回randint(1,10)
def清理(自):
打印(“清理代码”)
对于Iterable(5)中的x:
打印(x)

正如我在评论中所说:


当完成迭代时,您应该引发
StopIteration
异常,此时您应该已经知道必须执行清理,否则该迭代器将永远运行

此外,迭代器和iterable是不同的东西,来自fluent python书籍:

迭代器

实现next无参数方法的任何对象 返回序列中的下一项,或在出现时引发StopIteration 没有其他物品了。Python迭代器还实现了iter方法 因此,它们也是可移植的

其中:

iter内置函数可以从中获得的任何对象 迭代器。对象实现返回 迭代器是可迭代的


所以迭代器应该知道它什么时候结束,希望这段代码能把事情弄清楚:

from random import randint

class MyIterator:
  def __init__(self, n):
    self.n = n
    self.i = 0

  def __iter__(self):
    return self

  def __next__(self):
    if self.i < self.n:
      self.i += 1
      return randint(1, 10)
    else:
      print("doing cleanup")
      #do the clean up you want
      raise StopIteration()

class MyIterable:
    def __init__(self, n):
      self.n = n
    def __iter__(self):
        return MyIterator(self.n)

for x in MyIterable(5):
  print(x)

注意:在这里最好使用生成器函数或表达式,但这会使事情更容易区分。

您混合了两个不同的概念--可重用函数和迭代器。Iterable的
\uuuuuuuuuuuuuuuuuuuuuuuuu
应返回迭代器对象。虽然迭代器的
\uuu iter\uu
应该返回
self
。我知道我可以使用上下文管理器,但最好不用这样做@杰克,你不可能总是得到你想要的。所以答案是否定的。注意,您已经定义了一个迭代器,注意仅仅是一个iterable。@TomKarzes-huh?当完成迭代时,您应该引发
StopIteration
异常,此时您应该已经知道您必须执行清理,否则该迭代器将永远运行。无限迭代器没有任何错误或异常。这可能是。但是考虑到手头的任务:如果清理步骤应该由迭代器完成,您将如何调用它?“因此迭代器应该知道它何时结束”无限迭代器(不知道何时结束的迭代器)没有任何错误或异常@juanpa.arrivillaga当然,事实上标准库有无限迭代器,但大多数情况下,你会知道它什么时候结束。
4
9
7
5
1
doing cleanup