我需要看门狗机制来防止无限循环。看起来像这样:
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魔术可以使这段代码优雅?
答案 0 :(得分:3)
将生成器实例化为对象,然后调用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循环内。
答案 1 :(得分:1)
您可以从islice
导入itertools
并这样写:
for _ in islice(iter(foo, False), n):
# do stuff
只要不产生foo
,但最多产生False
次,它将调用n
。
但是,我个人喜欢
for _ in range(n):
if not foo():
break
# do stuff
更好。它长了两行,但可读性更高。
答案 2 :(得分:-1)
只需使用一个计数器即可。
count = 0
while not foo():
count += 1
if count > 1000:
break
# Do things and stuff here