Movatterモバイル変換


[0]ホーム

URL:


— FREE Email Series —

🐍 Python Tricks 💌

Python Tricks Dictionary Merge

🔒 No spam. Unsubscribe any time.

Browse TopicsGuided Learning Paths
Basics Intermediate Advanced
apibest-practicescareercommunitydatabasesdata-sciencedata-structuresdata-vizdevopsdjangodockereditorsflaskfront-endgamedevguimachine-learningnumpyprojectspythontestingtoolsweb-devweb-scraping

Table of Contents

Recommended Video Course
Raising and Handling Python Exceptions

An Introduction to Python Exceptions

Python Exceptions: An Introduction

bySaid van de Klundert Dec 01, 2024basicspython

Table of Contents

Remove ads

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding:Raising and Handling Python Exceptions

Python exceptions provide a mechanism for handling errors that occur during the execution of a program. Unlike syntax errors, which are detected by the parser, Python raises exceptions when an error occurs in syntactically correct code. Knowing how to raise, catch, and handle exceptions effectively helps to ensure your program behaves as expected, even when encountering errors.

By the end of this tutorial, you’ll understand that:

  • Exceptions in Python occur whensyntactically correct code results in anerror.
  • Thetryexcept block lets you execute code and handle exceptions that arise.
  • You can use theelse, andfinallykeywords for more refinedexception handling.
  • It’sbad practice tocatch all exceptions at once usingexcept Exception or the bareexcept clause.
  • Combiningtry,except, andpass allows your program tocontinue silently without handling the exception.

In this tutorial, you’ll get to know Python exceptions and all relevant keywords for exception handling by walking through a practical example of handling a platform-related exception. Finally, you’ll also learn how to create your own custom Python exceptions.

Get Your Code:Click here to download the free sample code that shows you how exceptions work in Python.

Take the Quiz: Test your knowledge with our interactive “Python Exceptions: An Introduction” quiz. You’ll receive a score upon completion to help you track your learning progress:


An Introduction to Python Exceptions

Interactive Quiz

Python Exceptions: An Introduction

In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block.

Understanding Exceptions and Syntax Errors

Syntax errors occur when the parser detects an incorrect statement. Observe the following example:

Python Traceback
>>> print(0 / 0))  File"<stdin>", line1print(0/0))^SyntaxError:unmatched ')'

The arrow indicates where the parser ran into thesyntax error. Additionally, the error message gives you a hint about what went wrong. In this example, there was one bracket too many. Remove it and run your code again:

Python
>>>print(0/0)Traceback (most recent call last):  File"<stdin>", line1, in<module>ZeroDivisionError:division by zero

This time, you ran into anexception error. This type of error occurs whenever syntactically correct Python code results in an error. The last line of the message indicates what type of exception error you ran into.

Instead of just writingexception error, Python details whattype of exception error it encountered. In this case, it was aZeroDivisionError. Python comes withvarious built-in exceptions as well as the possibility to create user-defined exceptions.

Raising an Exception in Python

There are scenarios where you might want to stop your program by raising an exception if a condition occurs. You can do this with theraise keyword:

Illustration of  raise statement usage

You can even complement the statement with a custom message. Assume that you’re writing a tiny toy program that expects only numbers up to5. You can raise an error when an unwanted condition occurs:

Pythonlow.py
number=10ifnumber>5:raiseException(f"The number should not exceed 5. ({number=})")print(number)

In this example, you raised anException object and passed it an informative custom message. You built the message using anf-string and aself-documenting expression.

When you runlow.py, you’ll get the following output:

Python Traceback
Traceback (most recent call last):  File"./low.py", line3, in<module>raiseException(f"The number should not exceed 5. ({number=})")Exception:The number should not exceed 5. (number=10)

The program comes to a halt and displays the exception to yourterminal orREPL, offering you helpful clues about what went wrong. Note that the final call toprint() never executed, because Python raised the exception before it got to that line of code.

With theraise keyword, you can raise any exception object in Python and stop your program when an unwanted condition occurs.

Debugging During Development Withassert

Before moving on to the most common way of working with exceptions in Python usingthetryexcept block, you’ll take a quick look at an exception that’s a bit different than the others.

Python offers a specific exception type that you should only use when debugging your program during development. This exception is theAssertionError. TheAssertionError is special because you shouldn’t ever raise it yourself usingraise.

Instead, you usetheassert keyword to check whether a condition is met and let Python raise theAssertionError if the condition isn’t met.

The idea of an assertion is that your program should only attempt to run if certain conditions are in place. If Python checks your assertion and finds that the condition isTrue, then that is excellent! The program can continue. If the condition turns out to beFalse, then your program raises anAssertionError exception and stops right away:

Python assert statement

Revisit your tiny script,low.py, fromthe previous section. Currently, you’re explicitly raising an exception when a certain condition isn’t met:

Pythonlow.py
number=1ifnumber>5:raiseException(f"The number should not exceed 5. ({number=})")print(number)

Assuming that you’ll handle this constraint safely for your production system, you could replace thisconditional statement with an assertion for a quick way to retain this sanity check during development:

Pythonlow.py
number=1assert(number<5),f"The number should not exceed 5. ({number=})"print(number)

If thenumber in your program is below5, then the assertion passes and your script continues with the next line of code. However, if you setnumber to a value higher than5—for example,10—then the outcome of the assertion will beFalse:

Pythonlow.py
number=10assert(number<5),f"The number should not exceed 5. ({number=})"print(number)

In that case, Python raises anAssertionError that includes the message you passed, and ends the program execution:

Shell
$pythonlow.pyTraceback (most recent call last):  File "./low.py", line 2, in <module>    assert (number < 5), f"The number should not exceed 5. ({number=})"            ^^^^^^^^^^AssertionError: The number should not exceed 5. (number=10)

In this example, raising anAssertionError exception is the last thing that the program will do. The program will then come to halt and won’t continue. The call toprint() that follows the assertion won’t execute.

Using assertions in this way can be helpful when you’re debugging your program during development because it can be quite a fast and straightforward to add assertions into your code.

However, you shouldn’t rely on assertions for catching crucial run conditions of your program in production. That’s because Python globally disables assertions when you run it in optimized mode using the-O and-OO command line options:

Shell
$python-Olow.py10

In this run of your program, you used the-O command line option, which removes allassert statements. Therefore, your script ran all the way to the end and displayed a number that isdreadfully high!

Note: Alternatively, you can also disable assertions through thePYTHONOPTIMIZE environment variable.

In production, your Python code may run using this optimized mode, which means that assertions aren’t a reliable way to handle runtime errors in production code. They can be quick and useful helpers when your debugging your code, but you should never use assertions to set crucial constraints for your program.

Iflow.py should reliably fail whennumber is above5, then it’s best to stick withraising an exception. However, sometimes you might not want your program to fail when it encounters an exception, so how should you handle those situations?

Handling Exceptions With thetry andexcept Block

In Python, you use thetry andexcept block to catch and handle exceptions. Python executes code following thetry statement as a normal part of the program. The code that follows theexcept statement is the program’s response to any exceptions in the precedingtry clause:

Diagram showing try and except statements

As you saw earlier, when syntactically correct code runs into an error, Python will raise an exception error. This exception error will crash the program if you don’t handle it. In theexcept clause, you can determine how your program should respond to exceptions.

The following function can help you understand thetry andexcept block:

Pythonlinux_interaction.py
deflinux_interaction():importsysif"linux"notinsys.platform:raiseRuntimeError("Function can only run on Linux systems.")print("Doing Linux things.")

Thelinux_interaction() can only run on a Linux system. Python will raise aRuntimeError exception if you call it on an operating system other then Linux.

Note: Picking the right exception type can sometimes be tricky. Python comes withmany built-in exceptions that arehierarchically related, so if you browse the documentation, you’re likely to find a fitting one.

Python even groups some of the exceptions into categories, such aswarnings that you should use to indicate warning conditions, andOS exceptions that Python raises depending on system error codes.

If you still didn’t find a fitting exception, then you cancreate a custom exception.

You can give the function atry by adding the following code:

Pythonlinux_interaction.py
# ...try:linux_interaction()except:pass

The way you handled the error here is by handing out apass. If you run this code on a macOS or Windows machine, then you get the following output:

Shell
$pythonlinux_interaction.py

You got nothing in response. The good thing here is that your program didn’t crash. But letting an exception that occurred pass silently is bad practice. You should always at least know about andlog if some type of exception occurred when you ran your code.

To this end, you can changepass into something that generates an informative message:

Pythonlinux_interaction.py
# ...try:linux_interaction()except:print("Linux function wasn't executed.")

When you now execute this code on a macOS or Windows machine, you’ll see the message from yourexcept block printed to the console:

Shell
$pythonlinux_interaction.pyLinux function wasn't executed.

When an exception occurs in a program that runs this function, then the program will continue as well as inform you about the fact that the function call wasn’t successful.

What you didn’t get to see was the type of error that Python raised as a result of the function call. In order to see exactly what went wrong, you’d need to catch the error that the function raised.

The following code is an example where you capture theRuntimeError and output that message to your screen:

Pythonlinux_interaction.py
# ...try:linux_interaction()exceptRuntimeErroraserror:print(error)print("The linux_interaction() function wasn't executed.")

In theexcept clause, you assign theRuntimeError to the temporary variableerror—often also callederr—so that you can access the exception object in the indented block. In this case, you’re printing the object’s string representation, which corresponds to the error message attached to the object.

Running this function on a macOS or Windows machine outputs the following:

Shell
$pythonlinux_interaction.pyFunction can only run on Linux systems.The linux_interaction() function wasn't executed.

The first message is theRuntimeError, informing you that Python can only execute the function on a Linux machine. The second message tells you which function wasn’t executed.

In the example above, you called a function that you wrote yourself. When you executed the function, you caught theRuntimeError exception and printed it to your screen.

Here’s another example where you open a file and use a built-in exception:

Pythonopen_file.py
try:withopen("file.log")asfile:read_data=file.read()except:print("Couldn't open file.log")

Iffile.log doesn’t exist, then this block of code will output the following:

Shell
$pythonopen_file.pyCouldn't open file.log

This is an informative message, and your program will still continue to run. However, yourexcept block will currently catchany exception, whether that’s related to not being able to open the file or not. You could lead yourself onto a confusing path if you see this message even when Python raises a completely unrelated exception.

Therefore, it’s always best to bespecific when you’re handling an exception.

In thePython docs, you can see that there are a couple of built-in exceptions that you could raise in such a situation, for example:

exceptionFileNotFoundError

Raised when a file or directory is requested but doesn’t exist. Corresponds to errno ENOENT. (Source)

You want to handle the situation when Python can’t find the requested file. To catch this type of exception and print it to screen, you could use the following code:

Pythonopen_file.py
try:withopen("file.log")asfile:read_data=file.read()exceptFileNotFoundErrorasfnf_error:print(fnf_error)

In this case, iffile.log doesn’t exist, then the output will be the following:

Shell
$pythonopen_file.py[Errno 2] No such file or directory: 'file.log'

You can have more than one function call in yourtry clause and anticipate catching various exceptions. Something to note here is that the code in thetry clause will stop as soon as it encounters any one exception.

Warning: When you use a bareexcept clause, then Python catches any exception that inherits fromException—which are most built-in exceptions! Catching the parent class,Exception, hides all errors—even those which you didn’t expect at all. This is why you should avoid bareexcept clauses in your Python programs.

Instead, you’ll want to refer tospecific exception classes that you want to catch and handle. You can learn more about why this is a good ideain this tutorial.

Look at the following code. Here, you first calllinux_interaction() and then try to open a file:

Pythonlinux_interaction.py
# ...try:linux_interaction()withopen("file.log")asfile:read_data=file.read()exceptFileNotFoundErrorasfnf_error:print(fnf_error)exceptRuntimeErroraserror:print(error)print("Linux linux_interaction() function wasn't executed.")

If you run this code on a macOS or Windows machine, then you’ll see the following:

Shell
$pythonlinux_interaction.pyFunction can only run on Linux systems.Linux linux_interaction() function wasn't executed

Inside thetry clause, you ran into an exception immediately and didn’t get to the part where you attempt to openfile.log. Now look at what happens when you run the code on a Linux machine if the file doesn’t exist:

Shell
$pythonlinux_interaction.py[Errno 2] No such file or directory: 'file.log'

Note that if you’re handling specific exceptions as you did above, then the order of theexcept clauses doesn’t matter too much. It’s all about which of the exceptions Python raises first. As soon as Python raises an exception, it checks the except clauses from top to bottom and executes the first matching one that it finds.

Here are the key takeaways about using Python’stryexcept statements:

  • Python executes atry clause up until the point where it encounters the first exception.
  • Inside theexcept clause—the exception handler—you determine how the program responds to the exception.
  • You can anticipatemultiple exceptions and differentiate how the program should respond to them.
  • Avoid using bareexcept clauses, because they can hide unexpected exceptions.

While usingtry together withexcept is probably the most common error handling that you’ll encounter, there’s more that you can do to fine-tune your program’s response to exceptions.

Proceeding After a Successful Try Withelse

You can use Python’selse statement to instruct a program to execute a certain block of code only in the absence of exceptions:

Diagram of try, except, and else statements in Python

Look at the following example:

Pythonlinux_interaction.py
# ...try:linux_interaction()exceptRuntimeErroraserror:print(error)else:print("Doing even more Linux things.")

If you were to run this code on a Linux system, then the output would be the following:

Shell
$pythonlinux_interaction.pyDoing Linux things.Doing even more Linux things.

Because the program didn’t run intoany exceptions, Python executed the code in theelse clause. However, if you run this code on a macOS or Windows system, then you get a different output:

Shell
$pythonlinux_interaction.pyFunction can only run on Linux systems.

Thelinux_interaction() function raised aRuntimeError. You’ve handled the exception, so your program doesn’t crash, and instead prints the exception message to the console. The code nested under theelse clause, however, doesn’t execute, because Python encountered an exception during execution.

Note that structuring your code like this is different from just adding the call toprint() outside of the context of thetryexcept block:

Pythonlinux_interaction.py
# ...try:linux_interaction()exceptRuntimeErroraserror:print(error)print("Doing even more Linux things.")

If you don’t nest theprint() call under theelse clause, then it’ll execute even if Python encounters theRuntimeError that you handle in theexcept block above. On a Linux system, the output would be the same, but on macOS or Windows, you’d get the following output:

Shell
$pythonlinux_interaction.pyFunction can only run on Linux systems.Doing even more Linux things.

Nesting code under theelse clause assures that it’ll only run when Python doesn’t encounter any exception when executing thetryexcept block.

You can also create a nestedtryexcept block inside theelse clause and catch possible exceptions there as well:

Pythonlinux_interaction.py
# ...try:linux_interaction()exceptRuntimeErroraserror:print(error)else:try:withopen("file.log")asfile:read_data=file.read()exceptFileNotFoundErrorasfnf_error:print(fnf_error)

If you were to execute this code on a Linux machine, then you’d get the following result:

Shell
$pythonlinux_interaction.pyDoing Linux things.[Errno 2] No such file or directory: 'file.log'

From the output, you can see thatlinux_interaction() ran. Because Python encountered no exceptions, it attempted to openfile.log. That file didn’t exist, but instead of letting the program crash, you caught theFileNotFoundError exception and printed a message to the console.

Cleaning Up After Execution Withfinally

Imagine that you always had to implement some sort of action to clean up after executing your code. Python enables you to do so using thefinally clause:

Diagram explaining try except else finally statements

Have a look at the following example:

Pythonlinux_interaction.py
# ...try:linux_interaction()exceptRuntimeErroraserror:print(error)else:try:withopen("file.log")asfile:read_data=file.read()exceptFileNotFoundErrorasfnf_error:print(fnf_error)finally:print("Cleaning up, irrespective of any exceptions.")

In this code, Python will execute everything in thefinally clause. It doesn’t matter if you encounter an exception somewhere in any of thetryexcept blocks. Running the code on a macOS or Windows machine will output the following:

Shell
$pythonlinux_interaction.pyFunction can only run on Linux systems.Cleaning up, irrespective of any exceptions.

Note that the code inside thefinally block will execute regardless of whether or not you’re handling the exceptions:

Pythonlinux_interaction.py
# ...try:linux_interaction()finally:print("Cleaning up, irrespective of any exceptions.")

You simplified the example code from above, butlinux_interaction() still raises an exception on a macOS or Windows system. If you now run this code on an operating system other than Linux, then you’ll get the following output:

Shell
$pythonlinux_interaction.pyCleaning up, irrespective of any exceptions.Traceback (most recent call last):  ...RuntimeError: Function can only run on Linux systems.

Despite the fact that Python raised theRuntimeError, the code in thefinally clause still executed and printed the message to your console.

This can be helpful because even code outside of atryexcept block won’t necessarily execute if your script encounters an unhandled exception. In that case, your program will terminate and the codeafter thetryexcept block will never run. However, Python will still execute the code inside of thefinally clause. This helps you make sure that resources likefile handles anddatabase connections are cleaned up properly.

Creating Custom Exceptions in Python

With the large number of built-in exceptions that Python offers, you’ll likely find a fitting type when deciding which exception to raise. However, sometimes your code won’t fit the mold.

Python makes it straightforward to create custom exception types by inheriting from a built-in exception. Think back to yourlinux_interaction() function:

Pythonlinux_interaction.py
deflinux_interaction():importsysif"linux"notinsys.platform:raiseRuntimeError("Function can only run on Linux systems.")print("Doing Linux things.")# ...

Using aRuntimeError isn’t a bad choice in this situation, but it would be nice if your exception name was a bit more specific. For this, you can create a custom exception:

Pythonlinux_interaction.py
classPlatformException(Exception):"""Incompatible platform."""# ...

You generally create a custom exception in Python by inheriting fromException, which is the base class for most built-in Python exceptions as well. You could also inherit from a different exception, but choosingException is usually the best choice.

That’s really all that you need to do. In the code snippet above, you also added adocstring that describes the exception type and serves as the class body.

Note: Python requires some indented code in the body of your class. Alternatively to using the docstring, you could’ve also usedpass orthe ellipsis (...). However, adding a descriptive docstring adds the most value to your custom exception.

While you can customize your exception object, you don’t need to do that. It’s often enough to give your custom Python exceptions a descriptive name, so you’ll know what happened when Python raises this exception in your code.

Now that you’ve defined the custom exception, you can raise it like any other Python exception:

Pythonlinux_interaction.py
classPlatformException(Exception):"""Incompatible platform."""deflinux_interaction():importsysif"linux"notinsys.platform:raisePlatformException("Function can only run on Linux systems.")print("Doing Linux things.")# ...

If you now calllinux_interaction() on macOS or Windows, then you’ll see that Python raises your custom exception:

Shell
$pythonlinux_interaction.pyTraceback (most recent call last):  ...PlatformException: Function can only run on Linux systems.

You could even use your customPlatformException as a parent class for other custom exceptions that you could descriptively name for each of the platforms that users may run your code on.

Conclusion

At this point, you’re familiar with the basics of using Python exceptions. After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. You also learned how you can create your own custom exceptions.

In this article, you gained experience working with the following exception-related keywords:

  • raise allows you to raise an exception at any time.
  • assert enables you to verify if a certain condition is met and raises an exception if it isn’t.
  • In thetry clause, all statements are executed until an exception is encountered.
  • except allows you to catch and handle the exception or exceptions that Python encountered in thetry clause.
  • else lets you code sections that should run only when Python encounters no exceptions in thetry clause.
  • finally enables you to execute sections of code that should always run, whether or not Python encountered any exceptions.

Get Your Code:Click here to download the free sample code that shows you how exceptions work in Python.

You now understand the basic tools that Python offers for dealing with exceptions. If you’re curious about the topic and want to dive deeper, then take a look at the following tutorials:

What’s your favorite aspect of exception handling in Python? Share your thoughts in the comments below.

Frequently Asked Questions

Now that you have some experience with Python exceptions, you can use the questions and answers below to check your understanding and recap what you’ve learned.

These FAQs are related to the most important concepts you’ve covered in this tutorial. Click theShow/Hide toggle beside each question to reveal the answer.

Exceptions in Python are errors that occur during the execution of a program, disrupting the normal flow of the program.

You handle exceptions in Python using atryexcept block. Python executes the code in thetry block and if an exception occurs, it switches to executing the code in theexcept block to handle the exception. However, only the exceptions that are explicitly specified in theexcept block will be handled. If an exception is not caught, it’ll propagate up the call stack and may result in the termination of your program.

To catch all exceptions in Python, you can use a bareexcept clause or writeexcept Exception, but it’s recommended to catch specific exceptions to avoid masking unexpected errors.

In atryexcept block, Python executes the code undertry and if an exception occurs, it immediately jumps to theexcept block to handle it, allowing the program to continue running.

Usingtryexcept withpass allows the program to ignore the exception and continue execution without taking any specific action in response to the error. However, this practice can hide potential issues, making it harder to debug and maintain the code, so use it with caution. It’s generally better to either handle the exception explicitly or log it for debugging purposes.

You raise an exception in Python using theraise keyword followed by an exception object, which can include a custom message.

You can use theassert keyword to check if a condition is true during development. If the condition is false, it raises anAssertionError, which can help with debugging. Note that assertions can be disabled by running Python with the-O (optimize) flag. Therefore, you shouldn’t rely on assertions for critical checks in production code, as they may be ignored.

Thefinally clause contains code that will always execute after atry block, regardless of whether an exception was raised or not, ensuring necessary cleanup actions occur.

Take the Quiz: Test your knowledge with our interactive “Python Exceptions: An Introduction” quiz. You’ll receive a score upon completion to help you track your learning progress:


An Introduction to Python Exceptions

Interactive Quiz

Python Exceptions: An Introduction

In this quiz, you'll test your understanding of Python exceptions. You'll cover the difference between syntax errors and exceptions and learn how to raise exceptions, make assertions, and use the try and except block.

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding:Raising and Handling Python Exceptions

🐍 Python Tricks 💌

Get a short & sweetPython Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

AboutSaid van de Klundert

Said is a network engineer, Python enthusiast, and a guest author at Real Python.

» More about Said

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

MasterReal-World Python Skills With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

MasterReal-World Python Skills
With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students.Get tips for asking good questions andget answers to common questions in our support portal.


Looking for a real-time conversation? Visit theReal Python Community Chat or join the next“Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Topics:basicspython

Recommended Video Course:Raising and Handling Python Exceptions

Related Tutorials:

Keep reading Real Python by creating a free account or signing in:

Already have an account?Sign-In

Almost there! Complete this form and click the button below to gain instant access:

An Introduction to Python Exceptions

Python Exceptions: An Introduction (Sample Code)

🔒 No spam. We take your privacy seriously.


[8]ページ先頭

©2009-2025 Movatter.jp