python - 如何像调用函数一样调用迭代器
问题描述
我需要一个看门狗机制来防止无限循环。这看起来像这样:
def stop(n):
""" Returns False after n calls """
for _ in range(n):
yield True
yield False
我会这样使用它:
def foo():
# this is the function I have to watch
return True # not good!
while foo() and stop(1000):
# do some stuff
当然上面的代码不起作用,因为 stop(1000) 是一个迭代器。我可以通过使用全局变量来编写一个模仿 stop() 的函数,但它不会很 Pythonic。我也可以这样写:
for _ in range(n):
if not foo():
break
# do_some_stuff()
它有效,但不是很优雅,因为 range(n) 是次要的。是否有任何 Python 魔法可以让这段代码变得优雅?
解决方案
将生成器实例化为对象并调用next()
:
def stop(n):
""" Returns False after n calls """
for _ in range(n):
yield True
yield False
my_stop = stop(1000)
while not foo() and next(my_stop):
# do your things
这将确保它继续返回到生成器的同一实例并在 1000 次尝试后停止。另外据我推测,您似乎打算在foo()
返回时打破True
?如果是这样,则应not foo()
改为捕获。
虽然完全是 Pythonic,但我认为只使用 for 循环:
# Just realized @timgeb answered the same alternative...
for _ in range(1000):
if foo():
break
您的stop()
生成器实际上与 for 循环做同样的事情,只是返回它是否仍在 for 循环内。