I like to avoid the "look before you leap" paradigm because I value easy-to-read code. In some cases, I cannot predict whether an error will occur, such as resource availability or out-of-memory errors. I haven't found a clean way of writing code that is repetitious or lengthy to handle these scenarios.
The following example is marginally readable, but duplicate code is unacceptable.
try:
myobject.write(filename)
except OSError:
if prompt("%s is in use by another application." +
"Close that application and try again.") == "Try again":
myobject.write(filename) #repeated code
In order to remove the duplicate code, I must add a few more lines and indent everything, reducing the readability.
success = False
while not success:
try:
myobject.write(filename)
success = True
except OSError:
if prompt("%s is in use by another application." +
"Close that application and try again.") != "Try again":
break
Is there a shorter way of writing this in Python that doesn't duplicate code?
Aside from switching to while True
, you could add a retry
decorator, and move your retry-able code to a function decorated by retry
:
from functools import wraps
from functools import update_wrapper
def retry(prompt_text="An error occured! Retry (y/n)?",
prompt_match='y',
exception=Exception):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
while True:
try:
ret = func(*args, **kwargs)
break
except exception:
if raw_input(prompt_text) == prompt_match:
ret = None
break
return ret
return update_wrapper(wrapper, func)
return decorator
@retry(prompt_text="your prompt: ", prompt_match="quit", exception=OSError)
def do_write(myobject, filename):
myobject.write(filename)
if __name__ == "__main__":
myobject = ...
filename = ...
do_write(myobject, filename) # This will be retried.
It's probably only worth the effort if you're using this pattern in more than one place, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With