Agree with that "try except" is better than "if else" for file handling ("with" is even better).
I am not sure if "try except" is really faster than "if else" in some edge cases in a memoization context, as you claim.
What I am sure is that in a didactic context, where you want people to understand code, something like:
if args not in stored_results:
stored_results[args] = fn(*args)
return stored_results[args]
is much better than that (from the OP): try:
# try to get the cached result
return stored_results[args]
except KeyError:
# nothing was cached for those args. let's fix that.
result = stored_results[args] = fn(*args)
return result