I had a function that returned a random member of several groups in order of preference. It went something like this:
def get_random_foo_or_bar():
"I'd rather have a foo than a bar."
if there_are_foos():
return get_random_foo()
if there_are_bars():
return get_random_bar()
raise IndexError, "No foos, no bars"
However, the first thing get_random_foo
does is verify there are foos and raise an IndexError
if not, so there_are_foos
is redundant. Moreover, a database is involved and using separate functions creates a concurrency issue. Accordingly, I rewrote it something like this:
def get_random_foo_or_bar():
"Still prefer foos."
try:
return get_random_foo()
except IndexError:
pass
try:
return get_random_bar()
except IndexError:
pass
raise IndexError, "No foos, no bars"
But I find this much less readable, and as I've never had reason to use pass
before it feels instictively wrong.
Is there a neater efficient pattern, or should I learn to accept pass
?
Note: I'd like to avoid any nesting since other types may be added later.
Edit
Thanks everyone who said that pass
is fine - that's reassuring!
Also thanks to those who suggested replacing the exception with a return value of None
. I can see how this is a useful pattern, but I would argue it's semantically wrong in this situation: the functions have been asked to perform an impossible task so they should raise an exception. I prefer to follow the behaviour of the random
module (eg. random.choice([])
).