Show both the EAFP and the LBYL style for the same Python operation.
The two styles are the same logic written in the opposite order.
def eafp_get(mapping, key):
try:
return mapping[key]
except KeyError:
return None
def lbyll_get(mapping, key):
if key in mapping:
return mapping[key]
return None
data = {'a': 1}
print(eafp_get(data, 'a')) # 1
print(eafp_get(data, 'z')) # None
print(lbyll_get(data, 'a')) # 1
print(lbyll_get(data, 'z')) # None
EAFP, which stands for "easier to ask forgiveness than permission", tries the operation and handles the failure if it happens. LBYL, which stands for "look before you leap", checks that the condition is true first and only acts when it is. Both versions produce the same output in the example above.
The real difference shows up when more than one thing is running at the same time. The LBYL version performs two separate operations, which are the membership test and the lookup. Between those two steps another thread can remove the key, and then the second operation raises KeyError anyway. The EAFP version performs one operation, so it either succeeds or fails as a single step. The race window in LBYL is small, but it is real, and the same argument applies to os.path.exists followed by open.
There is also a performance argument in favour of EAFP. In the common case where the key does exist, EAFP does one hash lookup. LBYL does two, one for the membership test and one for the retrieval, so it always does more work on the happy path.