4 ms·
I disagree with promoting try / catch. Exceptions like ValueError can really happen almost anywhere, so it is usually better to sanitize your inputs. E.g. som
by csense 13y ago
I disagree with promoting try / catch. Exceptions like ValueError can really happen almost anywhere, so it is usually better to sanitize your inputs.
E.g. something like:
try:
something = myfunc(d['x'])
except ValueError:
something = None
The programmer's intent is probably to only catch errors in the key lookup d['x'], but if there is some bug in the implementation of myfunc() or any of the functions called by myfunc() which causes a ValueError to unintentionally be raised, it will be caught by the except.
For dictionary lookups specifically, get() is usually preferable:
something = d.get('x')
if something is not None:
something = myfunc(something)
Or if dictionary may potentially contain None values:
if 'x' in d:
something = myfunc(d['x'])
- middleclick 13y agoWhile not disagreeing with your case, there are some cases where I try to follow this rule because in most of those cases, I would expect that there is no exception and if there is, then catch it. try: open(FILE) except IOError: it failed
- eliteraspberrie 13y agoAlso note the second argument to the get method specifies the default value to return in case of a KeyError: something = d.get('x', default)
- drakeandrews 13y agoThat example would surely be better as: something = myfunc(d['x']) if 'x' in d else None
- prawks 13y agoDoesn't this go against the Pythonic notion of handling exceptions rather than "looking before you leap"?
- wiredfool 13y agoThat looks like perl.
- calroc 13y agoIn this form you perform the lookup twice: once to test 'x' in d and then again to actually get the value d['x']. Try clauses in Python are very inexpensive if they pass (don't raise an exception), so often the try..except version would be preferable. In any event don't optimize prematurely and use a profiler rather than guessing if performance is an issue. ;-)
- smnrchrds 13y agoNot to counter your point, but I would like to quote from PEP8 here: Additionally, for all try/except clauses, limit the try clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs. Yes: try: value = collection[key] except KeyError: return key_not_found(key) else: return handle_value(value) No: try: # Too broad! return handle_value(collection[key]) except KeyError: # Will also catch KeyError raised by handle_value() return key_not_found(key)
- yetanotherphd 13y agoThese two comments together make a lot of sense. When your try block is a single lookup, you might as well use an if statement or get. However, when the 'absolute minimum' is nontrivial try/except is still a good option, e.g. try: name = employee['name'] first_name = name['first_name'] last_name = name['last_name'] except KeyError: print "Bad employee data" return
- GFK_of_xmaspast 13y agowhat's going to happen in your second example if somebody gives you a defaultdict instead of a regular dict for d.