5 ms·
This covers it very well: https://devblogs.microsoft.com/python/idiomatic-python-eafp-versus-lbyl/ https://devblogs.microsoft.com/python/idiomatic-python-eafp
by ghshephard 5y ago
This covers it very well: https://devblogs.microsoft.com/python/idiomatic-python-eafp-versus-lbyl/ https://devblogs.microsoft.com/python/idiomatic-python-eafp-...
In particular, this is not idiomatic python:
if "key" in dict_:
value += dict_["key"]
But this is:
try:
value += dict_["key"]
except KeyError:
pass
I too hate using the exception handling in this way, and if you aren't careful, you end up papering over other unexpected exceptions in your code, so you have to be (A) very specific in the exception you catch, and (B) keep it in as small a portion of code as possible.
I just think it makes for clumsy code - which of the two look better:
try:
value = dict_["key"]
except KeyError:
pass
else:
do_something(value)
OR
if "key" in dict_:
do_something(dict["key"])
But it might just be me.
- zohch 5y ago> In particular, this is not idiomatic python According to this article, I think his case is rather weak. The conclusion does not seem to follow from the premise to me.
- mywittyname 5y agoIf you don't care about a key existing, then this works. do_something(dict_.get("key", None)) I use that a lot for data parsing. Passing the exception is not very clean IMHO. I stick to d[key] nomenclature when I need assurance that all the keys are present in the dictionary, and .get(key,None) when I don't.
- stevesimmons 5y ago.get("key") is enough, as the default is already None. And if you care about the default value being a particular type, when there may also be None in the input stream, do something like: x.get("key") or [] or str(x.get("key") or "") # Guarantee strings and avoid "None"!
- stevesimmons 5y agoThe difference in your "which of the two look better" example is: (a) has one dict operation plus an exception which rarely occurs and is nearly zero cost if it doesn't. versus (b) has nearly always two dict operations, plus a possibly incorrect assumption that the dict will not be mutated between the "if key in dict" and "dict[key]" operations.
- dec0dedab0de 5y agoIf I find if's and try's looking ugly for a particular use case I try to figure out how to get rid of them. For your first example I would do this, assuming value is a number. value += dict_.get('key',0) Though I agree with using an if in the second example, if there isn't a better way to do the iteration to avoid looking up keys that don't exist.
- stubish 5y agoThe second 'key in dict' option is not thread safe if dict_ is not local (another thread may delete the entry between the existence check and use). This is a good reason why the exception handling approach is a better idiom. The exception handling approach may also be faster if your code cares (may, because I don't know if the cost of calculating the hash of "key" twice is cheaper than the exception handling overhead).