在Python中n次失败后退出无界循环的最佳方法是什么?
我是Python的新手。我想知道在在Python中n次失败后退出无界循环的最佳方法是什么?,python,python-2.7,loops,Python,Python 2.7,Loops,我是Python的新手。我想知道在n失败后如何退出无界的循环。对我来说,使用计数器似乎是不和谐的。 这是我的代码: while(True): #get trigger state trigState = scope.ask("TRIG:STATE?") #check if Acq complete if( trigState.endswith('SAVE') ): print 'Acquisition complete. Writing into fil
n
失败后如何退出无界的循环。对我来说,使用计数器似乎是不和谐的。
这是我的代码:
while(True):
#get trigger state
trigState = scope.ask("TRIG:STATE?")
#check if Acq complete
if( trigState.endswith('SAVE') ):
print 'Acquisition complete. Writing into file ...\n'
#save screen
#rewrite in file
#check if trigger is still waiting
elif( trigState.endswith('READY') ):
print 'Please wait ...\n'
#if trigger neither in SAVE nor in READY mode
else:
#THIS IS FAILURE!!!
print 'Failure: k tries remaining'
#wait for several seconds before next iteration
time.sleep(2)
请注意,循环必须是无界的-它可以任意迭代多次,直到超过尝试次数
是否有一种优雅(或至少是pythonic)的方法来满足这些要求?要成为“pythonic”,您需要编写符合的代码,相关规则如下:
显式比隐式好
可读性很重要
您应该明确说明允许的失败次数或剩余的失败次数。在前一种情况下:
for number_of_failures in range(MAX_FAILURE):
...
表达了这种意图,但很笨拙,因为每次循环都不一定会失败,所以在计算成功的次数时,你必须被扭曲,这会影响可读性。你可以选择:
number_of_failures = 0
while number_of_failures < MAX_FAILURES:
...
if this_is_a_failure_case:
number_of_failures += 1
...
这隐藏了退出案例。有时在中间退出循环是完全正确的,但是在你的情况下,在N次故障之后中止对你想做的事情非常重要,条件应该在while循环条件下。
您还可以根据剩余故障数重新表述:
failures_remaining = MAX_FAILURES
while failures_remaining > 0:
...
if this_is_a_failure_case:
failures_remaining -= 1
...
如果您喜欢函数式编程,可以摆脱循环并使用尾部递归:
def do_the_thing():
def try_it(failures_remaining = MAX_FAILURES):
...
failed = ....
...
try_it(failures_remaining-1 if failed else failures_remaining)
try_it()
但依我看,这并不是真正的进步。在Python中,我们喜欢直接而有意义。计数器可能听起来很笨重,但如果你把事情说得很好(毕竟你在计算失败次数,对吧?),你就安全地进入了Python代码的领域。例如,你可以使用
if
语句,并在n次尝试后引发错误。
您只需要一个限制
和一个计数器
while(True):
#get trigger state
limit = 5
counter = 0
trigState = scope.ask("TRIG:STATE?")
#check if Acq complete
if( trigState.endswith('SAVE') ):
print 'Acquisition complete. Writing into file ...\n'
#save screen
#rewrite in file
#check if trigger is still waiting
elif( trigState.endswith('READY') ):
print 'Please wait ...\n'
#if trigger neither in SAVE nor in READY mode
else:
#THIS IS FAILURE!!!
counter +=1
print 'Failure: ', limit - counter ,' tries remaining'
if k => limit: raise RuntimeError('too many attempts')
#wait for several seconds before next iteration
time.sleep(2)
…使用
if
语句对您的尝试进行编号对于您的目的来说似乎非常简单。它很简单,而且(在我看来)容易阅读,这符合你的标准
在while
循环中,您可以执行以下操作:
failure_no = 0
max_fails = n #you can substitute an integer for this variable
while:
#...other code
else:
failure_no += 1
if failure_no == max_fails:
break
print 'Failure: '+str(max_fails - failure_no)+' tries remaining'
这只会在满足else
/失败条件的情况下重复尝试次数,如果您想计算贯穿运行的总数,而不仅仅是失败,您可以将失败\u no+=1
放在while
之后,而不是放在else
块中
注意:你可以很容易地在你的逃生舱内放置一个通知:
乙二醇
使用计数器有什么问题?听起来这正是你所需要的。另外,你三次提到“无限”这个词,一次在标题中,两次在问题文本中。你能澄清你所说的无限是什么意思吗?如果你有办法退出循环,它怎么可能是无限的呢?确实,当失败次数少于n次时,循环会运行,也许我们永远不会遇到n次失败,但这并不意味着循环一定是无限的,只是无限的。“你这个词还有别的意思吗?”雷托尔,你说得对。这个词应该是无界的。使用计数器并不是非音速的——事实上,它让其他程序员非常清楚你的意图。我会说只要使用计数器不,你们的答案很好,我使用计数器。但我不知道我应该接受哪个答案。注意,Python中不推荐递归,因为它的堆栈限制相对较小,并且不会将递归函数优化为迭代函数。关于这个问题:
failure_no = 0
max_fails = n #you can substitute an integer for this variable
while:
#...other code
else:
failure_no += 1
if failure_no == max_fails:
break
print 'Failure: '+str(max_fails - failure_no)+' tries remaining'
if failure_no == max_fails:
print 'Maximum number of failures reached'
break