You may now create intricate scripts by beginning with functions and progressing to classes. These scripts will handle complex data, and you must ensure that they do not fail. In fact, a data-driven script must know what to do when the data is inaccurate. We cannot just assume that the user will submit correct information. While your knowledge may already help you avoid difficulties, we will learn today how to make your code error-tolerant. To do this, we will make use of a fantastic feature: Python Exceptions, or the famous
try ... except construct.
Table of Contents about Exceptions in Python: Managing Failures with Try-Except
Here’s what we are going to cover today:
When I first started coding, I couldn’t understand why a code might generate an error. In reality, the reasons of a mistake are many, and many of them are obvious. Of course, a code may have flaws that result in unanticipated problems, but this is not the only option. In actuality, the most common cause of a mistake is when the computer encounters unexpected data.
Errors may have a variety of reasons.
The classical example is the division by zero, which is not possible. No number, multiplied by 0, can generate a number different than zero: it is simply impossible. Thus, imagine we have the following code.
This works like a charm, as long as the user keeps giving us what we expect. Instead, if he gives us
0 as a second number, it will generate an error.
Looking at our first error
If we execute the code from the previous snippet, with zero as the second number, this will be the result.
C:\Users\aless\Desktop>python myscript.py Write the first number: 18 Write the second number: 0 Traceback (most recent call last): File "myscript.py", line 4, in print("Result is " + str(number_1/number_2)) ZeroDivisionError: division by zero
Don’t get scared by this message, it is extremely simple to understand. You can see the error message has four lines. We can analyze them in sequence.
Traceback (most recent call last):is simply indicating we have an error. Since we have an error at the root of our code, we will see just these four lines. But imagine you have a function, that calls a function, that calls another function and so on. You will have several lines of messages to identify when the error happened. We will see that later.
File "myscript.py", line 4, in <module>tells the file that generated the error and the module. Since we haven’t defined any module name, the module is replaced by the string
print("Result is " + str(number_1/number_2))is simply the line of code where the error happened.
ZeroDivisionError: division by zerotells you which type of error we encountered (
ZeroDivisionError) and an explicative message (
division by zero).
An error nested in a function
It is very unlikely that you will see errors at the root of your scope. Most likely, errors will happen inside a function or class method that is probably called from other scopes as well. Here is the exact same code as above, but with several functions to show you the point.
Here the error will be a little longer, but yet without additional complexity.
As we can see, the line indicating the file and the line indicating the piece of code generating the error are repeated. We start from the outer scope on top (line 13) to drill down until we reach the point where the error actually happened. This way you can quickly skim through your code. This is a lifesaver if you want to troubleshoot which function is passing parameters to the other in the wrong way.
Preventing python exceptions
The errors you see are the python exceptions because the code is handling with something unexpected. You can write code that generates no exception, simply with
else. Thus, we can rewrite our code above to prevent the error.
In case we attempt to give 0 as the second number, the script will recognize that before the error happens. This is a simple way to write code that deals with problems. It is completely okay, in fact, Google likes this coding style. However, this poses some serious limitations. Just continue reading to find out why.
Handling Python Exceptions
With the selection statement, you can only prevent exceptions. You cannot deal with them if they arise. Instead, to deal with them we have a special statement, the
try .. except. This construct is simple: Python will attempt to execute the code in the
try block. In case an exception arises, it will switch to the
Try to change your
division function to reflect the one below.
Every time the division is successful, the code inside except won’t be executed. Instead, if we put
num_2, Python will execute that code instead of performing the division.
Right now, you may think there is no advantage when comparing to exception prevention. However, exceptions raise to the outer scope until they find a
try ... except that handles them. This means we can take care of this error even in a different point of the code. We can change our script like the one below.
The real advantage of handling Python Exceptions
Why on earth would you need to handle exceptions apart from where they happen? Haha, this is a fantastic question, and the solution comes with practice. In certain instances, you wish to have some control over the mistakes in the outside scope.
The reason for it is simple that managing exceptions is a key component of your code, not just something you have to perform afterwards. A popular example is when designing a module, a library, or anything that other developers will utilize. You want to provide people the option to respond the way they desire in case of mistake. Thus, you construct functions that do not handle exceptions or merely handle part of them. The same is true when you wish to construct these libraries for yourself. You want your library to be general, therefore handling certain exceptions inside of it may not be a smart idea.
Remember, our purpose is not to be entirely mute on mistakes. Errors may still arise, and it is OK to convey them to users (maybe in a more legible style) (maybe in a more readable format). Instead, our major purpose is to guarantee that the software handles problems in the proper manner, and for some of them, the appropriate approach involves showing them to the user. Think about it, in our previous example, we didn’t change the program. We simply notified the individual that he was giving a terrible
Handling multiple exceptions
except statement, you can define which exception you wish to handle with it. This way, you can attach multiple
except statements to the same
try, so that each deals with a specific exception. This code is an example of that.
As you can see, the last statement does not specify any specific exception to handle. Thus, it will catch any error that is not
ValueError. However, the Python standards recommend you to not use just
except. Instead, you should always provide the error you are going to handle.
What if some error is not handled? You should know what are all the possible errors your code may generate, and handle them correctly with individual statements.
If you want, you can condense multiple errors in a single statement with brackets, like
try must have at least one
except. However, you can also attach a
finally statement after all your
except statements. Python will execute the code here in any case, after the
try (and the
except, if it was triggered). You need this construct if, for example, you need to close files or similar stuff.
Working on the exception
In the except statement, you might actually need to work on the exception you received. For example, you might want to store its error in a file. You can do that by assigning the exception received to a variable, with the keyword
In this snippet, we write the error number to a file. We do that by leveraging the
errno property of every error. We can also find the message in the
If you can handle Python Exceptions, it is only because someone else created them. The
ZeroDivisionError is embedded inside the division operand (
/), for example. The
ValueError can be triggered by the
int() function, and so on. Like someone defined these exceptions, you can tell your code when to generate exceptions. Here we have a cool example.
In this example, our script won’t output anything. Instead, it will only generate an error in case something is wrong. To generate an error, we use the keyword
raise. The keyword is “raise” because errors are meant to be raised to the outer scope, and so on until they are handled. To that keyword, we need to add the name of the error and any parameters it requires. Remember that errors are just objects like others.
Explaining the good stuff
In our example, we start by checking the absolute validity of day and month. In case they are wrong, we quickly raise an error with a description (as the
ValueError can accept that). However, the good stuff happens right after that.
In the second part of the function, we validate combination of month and day inside a
try block. In case something is wrong, we simply raise a
ValueError without description. The
try block will then switch to the
except block, and handle that error. Here we generate another error, and we add the message. This way we don’t need to write the same message three times. Pretty neat.
Custom Python Exceptions
Now you can raise existing Python exceptions, but sometimes you want to define your own. This is an advanced topic, as you need to define a class that inherits from another, and we haven’t talked about that yet. However, for now, just know that it is possible to have your own error with your own name. Simply use this construct.
As you can see, we simply define a class that gets its properties from the default
Exception class. We name our class ValidationError, yet we don’t define anything and instead use the keyword
pass. Once you will learn about inheritance, you will also learn about defining additional properties. As a naming convention, include “Error” in the name.
Default Python Exceptions
Python has a lot of pre-built errors. Below the ones you must know.
IndexErrorhappens when you have problems with lists, like if you are trying to access an item that does not exist.
NameErroris similar to the IndexError, but applies with dictionaries.
ValueErrorcomes when something is not of the type it should be. Maybe it was a string but should have been an integer – something like that.
EOFErrordeals with the end of a file. If you are reading a file, it might be corrupted. Most likely, you missed some brackets in your python file and thus Python does not know when to close them.
Now that you understand python exceptions and how to handle them, you should be able to write bug-free programs. Don’t worry if your code is still shaky at first; practice will make perfect. It’s a good idea to put your code to the test using odd inputs. Try inserting some text where you want to see numbers, or vice versa. Insert spaces at the start or end of user inputs, or provide a file of a different type instead of the expected one.
If Our Method Resolve Your Problem Consider To Share This Post, You can help more People Facing This Problem and also, if you want, you can Subscribe at Our Youtube Channel as Well!
What do you think about Python Exceptions? What plans do you have for them? What was the most difficult component about them? Let me know in the comments!