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
andexcept
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 break
s or return
s) 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
Filter Dataframe Rows If Value in Column Is in a Set List of Values
How to "Log In" to a Website Using Python'S Requests Module
How to Select a Drop-Down Menu Value With Selenium Using Python
Read Subprocess Stdout Line by Line
How to Hide Output of Subprocess
Pip Install' Fails For Every Package ("Could Not Find a Version That Satisfies the Requirement")
Explanation of How Nested List Comprehension Works
Why Does Substring Slicing With Index Out of Range Work
Find the Row Indexes of Several Values in a Numpy Array
How to Play Wav File in Python
How to Find the Location of My Python Site-Packages Directory
How to Overcome "Datetime.Datetime Not Json Serializable"
Is There Any Pythonic Way to Combine Two Dicts (Adding Values For Keys That Appear in Both)
What Is Getattr() Exactly and How to Use It
How to Split a String into a List of Characters
How to Concatenate Text Files in Python