我是Python的新手。我想知道如何在n
失败后退出无界循环。使用计数器似乎对我来说 unpythonic 。
这是我的代码:
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)的方法来满足要求?
答案 0 :(得分:3)
要成为“pythonic”,您需要编写符合Zen of Python的代码,并且相关规则如下:
明确比隐含更好。
可读性计数。
您应该明确说明您允许的失败次数或剩余的失败次数。在前一种情况下:
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
...
这很好,因为它说“如果我没有失败最多次,继续前进。这比一个好一点:
number_of_failures = 0
while True:
...
if this_is_a_failure_case:
number_of_failures += 1
...
if number_of_failures == MAX_FAILURES: #you could use >= but this isn't necessary
break
隐藏退出案例。有时在中间退出循环是完全正常的,但在你的情况下,在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中,我们喜欢直接而有意义。计数器可能听起来很笨重,但如果你说得好(毕竟你算错了,对吧?)你安全地处于Pythonic代码领域。
答案 1 :(得分:2)
使用if
语句对您的尝试进行编号似乎很简单。它很简单,而且(我的眼睛)很容易阅读,符合您的Pythonic标准。
在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
/失败条件时迭代尝试次数,如果你想计算总数,而不仅仅是失败,你可以将failure_no +=1
设置为正确在while
之后,而不是在else
区块内。
注意:您可以轻松地在逃生中添加通知:
例如
if failure_no == max_fails:
print 'Maximum number of failures reached'
break
答案 2 :(得分:1)
E.g。您可以使用if
语句并在n次尝试后引发错误。
您只需要limit
和counter
。
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)
...