There is a widespread belief that break and continue statements are a bad programming practice. See this StackOverflow thread for an discussion. They can make code less readable if they make the intent less clear. In some cases, though, I believe they are actually better than the alternatives and can improve readability.
Here's a recent example from working with AWS in Python.
ssm = boto3.client("ssm")
response = ssm.send_command(...)
command_id = response["Command"]["CommandId"]
while True:
invocation = ssm.get_command_invocation(... command_id ...)
if invocation['Status'] not in ['Pending', 'InProgress']
break
time.sleep(5)
This code sends a command to AWS SSM, and gets the status of the invocation in a loop, exiting when completed. It will also pause before retrying.
Note that the only way to terminate this loop is the break statement.
I thought of a few alternatives to avoid a break but actually like them less.
One option is to bootstrap an initial request outside the loop, so you can include the status directly on the while condition:
invocation = ssm.get_command_invocation(... command_id ...)
while invocation['Status'] not in ['Pending', 'InProgress']:
time.sleep(5)
invocation = ssm.get_command_invocation(... command_id ...)
I don't like this as much because of the duplication.
Another way to address this is by using a flag to indicate completion:
done = False
while not done:
invocation = ssm.get_command_invocation(... command_id ...)
done = invocation['Status'] not in ['Pending', 'InProgress']
time.sleep(5)
No duplication here, but the flag variable is extra clutter, and is not really that much more readable than the break version, because it's not obvious from the while statement itself what condition will cause the loop to terminate. Also, even if the loop completes on the first iteration, you still have to sleep before exiting the loop -- unless you add a break, in which case the flag is useless.
Compared to the other options, the original version with the while True / break feels like the least bad, even if that conclusion is unintuitive.
Top comments (2)
Which one would you pick?
Agreed. In this case avoiding "break" makes for less readable code.
I think the author of the SO answer is mostly saying to make them explicit, like you cloud do with "defensive" returns in a function.
return