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