What Is the Eafp Principle in Python

What is the EAFP principle in Python?

From the glossary:

Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

An example would be an attempt to access a dictionary key.

EAFP:

try:
x = my_dict["key"]
except KeyError:
# handle missing key

LBYL:

if "key" in my_dict:
x = my_dict["key"]
else:
# handle missing key

The LBYL version has to search the key inside the dictionary twice, and might also be considered slightly less readable.

Python Exceptions: EAFP and What is Really Exceptional?

exceptions should only be called in
truly exceptional cases

Not in Python: for example, every for loop (unless it prematurely breaks or returns) terminates by an exception (StopIteration) being thrown and caught. So, an exception that happens once per loop is hardly strange to Python -- it's there more often than not!

The principle in question may be crucial in other languages, but that's definitely no reason to apply that principle to Python, where it's so contrary to the language's ethos.

In this case I like Jon's rewrite (which should be further simplified by removing the else branch) because it makes the code more compact -- a pragmatical reason, most definitely not the "tempering" of Python style with an alien principle.

Concurrency implications of EAFP/LBYL

Your thoughts are correct. Some additional points:

If the attribute exists most of the time, try:except: might be much faster than
the LBYL idiom.

If you don't like the try: except: syntax, you can also write:

item = getattr(foo, 'bar', None)
if item is None:
....
else:
....

what is the elegant way to check if a nested list has and has NOT a value at a specific index?

Python's much loved EAFP approach with exception handling would be my way of doing it.

try:
print(ar[i][j]) # i -> row index, j -> col index
except IndexError:
print('Error!')

Another way, also known as the LYBL approach, would be using if checks:

if i < len(ar) and j < len(ar[i]):
print(ar[i][j])

And here's the "one liner" version (that kills readability, but you seem to want):

print(ar[i][j] if i < len(ar) and j < len(ar[i]) else "Error")

  • What is the EAFP principle in Python?
  • LBYL vs EAFP in Java? (the same concept applies to almost any language.)


Related Topics



Leave a reply



Submit