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

Python's Built-In Exceptions: A Walkthrough With Examples

Python's Built-in Exceptions: A Walkthrough With Examples

byLeodanis Pozo Ramosintermediatepython

Table of Contents

Remove ads

Python has a complete set ofbuilt-in exceptions that provide a quick and efficient way to handle errors and exceptional situations that may happen in your code. Knowing the most commonly used built-in exceptions is key for you as a Python developer. This knowledge will help you debug code because each exception has a specific meaning that can shed light on your debugging process.

You’ll also be able to handle and raise most of the built-in exceptions in your Python code, which is a great way to deal with errors and exceptional situations without having to create your own custom exceptions.

In this tutorial, you’ll:

  • Learn whaterrors andexceptions are in Python
  • Understand how Python organizes thebuilt-in exceptions in aclass hierarchy
  • Explore the mostcommonly used built-in exceptions
  • Learn how tohandle andraise built-in exceptions in your code

To smoothly walk through this tutorial, you should be familiar with some core concepts in Python. These concepts include Pythonclasses, classhierarchies,exceptions,tryexcept blocks, and theraise statement.

Get Your Code:Click here to download the free sample code that you’ll use to learn about Python’s built-in exceptions.

Take the Quiz: Test your knowledge with our interactive “Python's Built-in Exceptions: A Walkthrough With Examples” quiz. You’ll receive a score upon completion to help you track your learning progress:


Python's Built-In Exceptions: A Walkthrough With Examples

Interactive Quiz

Python's Built-in Exceptions: A Walkthrough With Examples

In this quiz, you'll test your understanding of Python's built-in exceptions. With this knowledge, you'll be able to effectively identify and handle these exceptions when they appear. Additionally, you'll be more familiar with how to raise some of these exceptions in your code.

Errors and Exceptions in Python

Errors andexceptions are important concepts in programming, and you’ll probably spend a considerable amount of time dealing with them in your programming career.Errors are concrete conditions, such assyntax andlogical errors, that make your code work incorrectly or even crash.

Often, you can fix errors by updating or modifying the code, installing a new version of a dependency, checking the code’s logic, and so on.

For example, say you need to make sure that a givenstring has a certain number of characters. In this case, you can use the built-inlen() function:

Python
>>>len("Pythonista")=10  File"<input>", line1...SyntaxError:cannot assign to function call here.    Maybe you meant '==' instead of '='?

In this example, you use the wrongoperator. Instead of using the equalitycomparison operator, you use theassignment operator. This code raises aSyntaxError, which represents a syntax error as its name describes.

Note: In the above code, you’ll note how nicely the error message suggests a possible solution for correcting the code. Starting in version3.10, the Python core developers have put a lot of effort into improving theerror messages to make them more friendly and useful for debugging.

To fix the error, you need to localize the affected code and correct the syntax. This action will remove the error:

Python
>>>len("Pythonista")==10True

Now the code works correctly, and theSyntaxError is gone. So, your code won’t break, and your program will continue its normal execution.

There’s something to learn from the above example. You can fix errors, but you can’thandle them. In other words, if you have a syntax error like the one in the example, then you won’t be able to handle that error and make the code run. You need to correct the syntax.

On the other hand,exceptions are events that interrupt the execution of a program. As their name suggests, exceptions occur inexceptional situations that should or shouldn’t happen. So, to prevent your program from crashing after an exception, you must handle the exception with the appropriate exception-handling mechanism.

To better understand exceptions, say that you have a Python expression likea + b. This expression will work ifa andb are both strings ornumbers:

Python
>>>a=4>>>b=3>>>a+b7

In this example, the code works correctly becausea andb are both numbers. However, the expression raises an exception ifa andb are of types that can’t be added together:

Python
>>>a="4">>>b=3>>>a+bTraceback (most recent call last):  File"<input>", line1, in<module>a+b~~^~~TypeError:can only concatenate str (not "int") to str

Becausea is a string andb is a number, your code fails with aTypeError exception. Since there is no way to add text and numbers, your code has faced an exceptional situation.

Python uses classes to represent exceptions and errors. These classes are generically known asexceptions, regardless of what a concrete class represents, an exception or an error. Exception classes give us information about anexceptional situation and alsoerrors detected during the program’s execution.

The first example in this section shows a syntax error in action. TheSyntaxError class represents an error but it’s implemented as a Python exception. This could be confusing, but Python uses exception classes for both errors and exceptions.

Another example of an exception could be when you’re working on a piece of code that processes a textfile, and that file doesn’t exist. In this case, you don’t have an error in your code. You have an exceptional situation that you need to handle to prevent the program from crashing. You have no control over the problem because you can’t ensure that the file exists by modifying your code. You need to handle the exception.

You can usetryexcept blocks to handle exceptions in Python. In the following section, you’ll learn the basics of how to do that handling.

Handling Exceptions

If you have a piece of code that raises an exception, and you don’t provide a handler code for that exception, then your program will stop running. After that, an exceptiontraceback will appear on the standard output, your screen.

Note: To learn the basics of exception handling in Python, check out thePython Exceptions: An Introduction tutorial.

In Python, you can handle exceptions using thetryexcept statement, which allows you to catch the exception and provide recuperative actions.

Consider the following example. A common exception that you’ll see when you start using Python’slists andtuples isIndexError. This exception happens when you try to access an index that’s out of range:

Python
>>>numbers=[1,2,3]>>>numbers[5]Traceback (most recent call last):...IndexError:list index out of range

In this example, the list of numbers only has three values. So, when you try to access index5 in anindexing operation, you get anIndexError that breaks the code. You can wrap up this code in atryexcept block to prevent the breakdown:

Python
>>>try:...numbers[5]...exceptIndexError:...print("Your list doesn't have that index 😔")...Your list doesn't have that index 😔

Now, the code doesn’t break with an exception. Instead, it prints a message to the screen. Note that the call toprint() is just a placeholder action for the sake of the example. In real-world code, you may do other things here.

The above example illustrates the most basic construct to handle exceptions in Python. You can check out the tutorial suggested above to dive deeper into exception handling. Now, it’s time to learn about the other side of the coin. You can also raise exceptions in Python.

Raising Exceptions

Python has theraise statement as part of itssyntax. You can use this statement to raise exceptions in your code as a response to exceptional situations.

Note: To dive deeper into raising exceptions in Python, check out thePython’s raise: Effectively Raising Exceptions in Your Code tutorial.

As an example of how to use theraise statement, say that you need to write a function for calculating the average grade of students. You come up with the following function:

Python
>>>defaverage_grade(grades):...returnsum(grades)/len(grades)...>>>average_grade([5,4,5,3])4.25>>>average_grade([])Traceback (most recent call last):...ZeroDivisionError:division by zero

This function works okay. However, when the list of grades is empty, you get a zero division error becauselen(grades) will be0. When the user of the code sees the error message, they may get confused. A zero division error? What’s causing this?

A better approach would probably be to make sure that the input list isn’t empty and raise a more appropriate exception if that’s the case:

Python
>>>defaverage_grade(grades):...ifnotgrades:...raiseValueError("empty grades not allowed")...returnsum(grades)/len(grades)...>>>average_grade([5,4,5,3])4.25>>>average_grade([])Traceback (most recent call last):...ValueError:empty grades not allowed

In this updated version ofaverage_grade(), you add aconditional statement that checks whether the input data is empty. If it is, you raise aValueError with an explicit error message that clearly communicates what’s wrong with the code.

TheIndexError andValueError exceptions are examples of commonly used built-in exceptions in Python. In the following sections, you’ll learn more about these and several other built-in exceptions.

This knowledge will help you in several ways. First, you’ll be able to quickly figure out the type of error you may have in your code, which improves your debugging skills. Second, you’ll be armed with a wide arsenal of already available exceptions to raise in your own code, freeing yourself from creating custom exceptions.

Python Built-in Exceptions

Python has over sixtybuilt-in exceptions that represent a wide range of common errors and exceptional situations. These exceptions are organized into two groups:

  1. Base class exceptions
  2. Concrete exceptions

The first group of exceptions comprises exception classes that are primarily used as base classes for other exceptions. For example, in this group, you have theException class, which is specially designed to allow you to createcustom exceptions.

The second group contains exceptions that you’ll commonly see in Python code or get while executing Python code. For example, you’ve probably seen some of the following concrete exceptions in your day-to-day coding:

Exception ClassDescription
ImportErrorAppears when animport statement can’t load a module
ModuleNotFoundErrorHappens whenimport can’t locate a given module
NameErrorAppears when a name isn’t defined in theglobal orlocal scope
AttributeErrorHappens when anattribute reference or assignment fails
IndexErrorOccurs when an indexing operation on asequence uses an out-of-range index
KeyErrorOccurs when a key is missing in adictionary or another mapping
ZeroDivisionErrorAppears when the second operand in a division ormodulo operation is0
TypeErrorHappens when an operation, function, or method operates on an object of inappropriate type
ValueErrorOccurs when an operation, function, or method receives the right type of argument but the wrong value

This table is just a small sample of Python’s built-in exceptions. You can find a comprehensive list of all the built-in exceptions in theBuilt-in Exceptions page of Python’s documentation.

Glancing at the Exceptions Hierarchy

As you already know, you’ll find many built-in exceptions in Python. You can explore them by inspecting thebuiltins namespace from a REPL session:

Python
>>>importbuiltins>>>dir(builtins)[    'ArithmeticError',    'AssertionError',    'AttributeError',    'BaseException',    ...]

In this example, you first import thebuiltinsnamespace. Then, you use the built-indir() function to list the names that this module defines. Note that you’ll get the complete list of built-in names. Between them, you’ll find the built-in exceptions.

Python’s built-in exceptions are coded asclasses and organized in aclass hierarchy that includes the following levels:

  • Base classes: They provide the base classes for other exceptions. You should only use them as parent classes. However, you might find some of these exceptions, such as theException class, in some codebases.
  • Concrete exceptions: They’re exceptions that Python will raise as a response to different exceptional situations. They also provide a great base of concrete exceptions that you can raise in your own code when appropriate.
  • OS exceptions: They provide exceptions that the operating system generates. Python passes them along to your application. In most cases, you’ll be catching these exceptions but not raising them in your code.
  • Warnings: They provide warnings about unexpected events or actions that could result in errors later. These particular types of exceptions don’t represent errors. Ignoring them can cause you issues later, but you can ignore them.

A diagram of the exception hierarchy is below:

BaseException ├── BaseExceptionGroup ├── GeneratorExit ├── KeyboardInterrupt ├── SystemExit └── Exception      ├── ArithmeticError      │    ├── FloatingPointError      │    ├── OverflowError      │    └── ZeroDivisionError      ├── AssertionError      ├── AttributeError      ├── BufferError      ├── EOFError      ├── ExceptionGroup [BaseExceptionGroup]      ├── ImportError      │    └── ModuleNotFoundError      ├── LookupError      │    ├── IndexError      │    └── KeyError      ├── MemoryError      ├── NameError      │    └── UnboundLocalError      ├── OSError      │    ├── BlockingIOError      │    ├── ChildProcessError      │    ├── ConnectionError      │    │    ├── BrokenPipeError      │    │    ├── ConnectionAbortedError      │    │    ├── ConnectionRefusedError      │    │    └── ConnectionResetError      │    ├── FileExistsError      │    ├── FileNotFoundError      │    ├── InterruptedError      │    ├── IsADirectoryError      │    ├── NotADirectoryError      │    ├── PermissionError      │    ├── ProcessLookupError      │    └── TimeoutError      ├── ReferenceError      ├── RuntimeError      │    ├── NotImplementedError      │    └── RecursionError      ├── StopAsyncIteration      ├── StopIteration      ├── SyntaxError      │    └── IndentationError      │         └── TabError      ├── SystemError      ├── TypeError      ├── ValueError      │    └── UnicodeError      │         ├── UnicodeDecodeError      │         ├── UnicodeEncodeError      │         └── UnicodeTranslateError      └── Warning           ├── BytesWarning           ├── DeprecationWarning           ├── EncodingWarning           ├── FutureWarning           ├── ImportWarning           ├── PendingDeprecationWarning           ├── ResourceWarning           ├── RuntimeWarning           ├── SyntaxWarning           ├── UnicodeWarning           └── UserWarning

Note that most classes in the hierarchy inherit fromException. This is also the base class that you should use in those situations when you need to create a custom exception.

Knowing the Base Exceptions

In the built-in exception hierarchy, you’ll find a few classes that are designed to be base classes. TheBaseException class is on the top. Then you have five subclasses:

Exception Base ClassDescription
BaseExceptionGroupCreates anexception group that wraps any exception rather than only those that inherit fromException
GeneratorExitOccurs when agenerator orcoroutine is closed
KeyboardInterruptHappens when the user presses the interrupt key combination, which normally isCtrl+C
SystemExitResults from calling thesys.exit() function, but you can also raise it directly
ExceptionProvides a base class for user-defined exceptions, which should be derived from this class

As you can see, all of these base exceptions have their specific use case. It’s important to note that you should useException and notBaseException when you create custom exceptions. That’s becauseBaseException should be used for exceptions that should never be caught in real code.

In practice, when catching and raising exceptions, you should use the most specific exception for the problem at hand.

For example, if you have a piece of code that can potentially raise aValueError, then you should explicitly handle this exception. If you useException instead ofValueError, then your code will catchException and all its subclasses, includingValueError. If your code ends up raising something different fromValueError, then that error will be mishandled.

Getting to Know Warnings

At the bottom of the exception hierarchy, you’ll find warnings. These are particular types of exceptions that denote something that can cause problems in the near future. Warnings are exceptions that pertain to thewarning categories.

Note: Because warnings are a type of exception with specific use cases and dedicated documentation, you won’t cover them in detail in this tutorial. You can check theWarning control page in Python’s documentation for a complete walkthrough of warnings.

Probably the most common warning that you’ll see while executing Python code isDeprecationWarning. This warning appears when you use deprecated features of the language. For example, Python 3.12 hasdeprecated thecalendar.January andcalendar.February constants:

Python
>>># Python 3.12.2>>>calendar.January<stdin>:1: DeprecationWarning: The 'January' attribute is deprecated,    use 'JANUARY' instead1

Even though the code works because the constants haven’t been removed yet, Python lets you know that the feature is deprecated to prevent you from having issues in the future. As the warning message says, now you should usecalendar.JANUARY.

Syntax Errors

The first exception that you’ll probably see in Python is theSyntaxError exception. Even though Python uses an exception class for this type of issue, you should be clear that they represent errors rather than exceptions. So you won’t be handling them but fixing them, as you already learned.

You’ll also find that Python defines a couple of additional exceptions that inherit fromSyntaxError:

These exceptions can be expected when you’re starting to learn Python, and they can confuse you. Fortunately, moderncode editors and IDE include features that spot and often remove the conditions that generate these exceptions. In the following sections, you’ll learn about this group of exceptions.

SyntaxError

When Python detects an invalid syntax in a piece of code, it raises aSyntaxError exception. The exception prints atraceback with helpful information that you can use todebug the error and fix your code.

Note: To learn more about syntax errors, check out theInvalid Syntax in Python: Common Reasons for SyntaxError tutorial.

There are many situations where you can end up with a syntax error in your code. You can forget a comma or a closing bracket, misuse an operator or a keyword, and more.

Here are a few examples:

Python
>>>numbers=[1,2,34]  File"<stdin>", line1numbers=[1,2,34]^^^SyntaxError:invalid syntax. Perhaps you forgot a comma?>>>7=7  File"<stdin>", line17=7^SyntaxError:cannot assign to literal here.    Maybe you meant '==' instead of '='?>>>class= "Economy"  File"<stdin>", line1class= "Economy"^SyntaxError:invalid syntax

These are common syntax errors that you can fall into at times. The good news is that with theimproved error messages that Python provides these days, you can quickly track down the error and fix it.

IndentationError

Unlike other programming languages, indentation is part of Python syntax. To delimit a code block in Python, you use indentation. Therefore, you may get an error if the indentation isn’t correct. Python uses theIndentationError exception to denote this problem.

You may encounter this exception when you’re starting to learn Python. It can also appear when you copy and paste code from intricate places. Fortunately, the error isn’t common nowadays because modern code editors can automatically fix code indentation.

To see the exception in action, consider the following example of a function whose code block uses non-uniform indentation:

Python
>>>defgreet(name):...print(f"Hello,{name}!")...print("Welcome to Real Python!")  File"<stdin>", line3print("Welcome to Real Python!")^IndentationError:unindent does not match any outer indentation level

In this example, the highlighted lines have different indentations. The first line is indented at four spaces, while the second line is indented at two spaces. This indentation mismatch triggers anIndentationError. Again, because this is a syntax error, Python reports it immediately. You can quickly fix the issue by correcting the indentation.

TabError

Another possible issue for those who come from other programming languages is to mix tab and space characters while indenting Python code. The exception for this issue isTabError, which is a subclass ofIndentationError. So, it’s another syntax error exception.

Note: The Style Guide for Python Code (PEP 8) explicitly says:

Spaces are the preferred indentation method.Tabs should be used solely to remain consistent with code that is already indented with tabs.Python disallows mixing tabs and spaces for indentation. (Source)

Here’s an example where Python raises aTabError exception:

Pythongreeting.py
defgreet(name):print(f"Hello,{name}!")print("Welcome to Real Python!")

In this example, the first line ingreet() is indented using a tab character, while the second line is indented using eight spaces, which is thecommon number of spaces that replaces a tab character.

Note: If you don’t use eight spaces in the second line, then you’ll get anIndentationError instead of aTabError.

To try out the example, go ahead and run the file from the command line:

Shell
$pythongreeting.py  File ".../greeting.py", line 3    print("Welcome to Real Python!")TabError: inconsistent use of tabs and spaces in indentation

Because the code indentation mixes tabs and spaces, you get aTabError indentation error. Again,TabError exceptions aren’t common nowadays because modern code editors can fix them automatically. So, if you have your editor well-set for Python development, then you probably won’t see this exception in action.

Import-Related Exceptions

Sometimes, when importingpackages, modules and their contents, your code fails with an error telling you that the target file wasn’t found. In practice, you can get one of two import-related exceptions:

Note that theModuleNotFoundError exception is a subclass ofImportError with a more specific meaning or goal, as you’ll learn in a moment.

In the following sections, you’ll learn about these two exceptions and when Python raises them. This knowledge will help you fix the problem and make your code work.

ModuleNotFoundError

As you’ve already learned, theModuleNotFoundError exception is a subclass ofImportError with a more specific goal. Python raises this exception when it can’t find the module from which you want to import something:

Python
>>>importnon_existingTraceback (most recent call last):...ModuleNotFoundError:No module named 'non_existing'

When Python doesn’t find the target module in its import search path, it raises aModuleNotFoundError exception. To fix this problem, you must ensure your module is listed insys.path.

Note: The best way to ensure that your module is available in Python’s path is toinstall it. You can usepip andinstall your local packages similarly to how you install packages fromPyPI.

BecauseModuleNotFoundError is a subclass ofImportError, when you explicitly use the latter in atryexcept block, you’ll be catching both exceptions. So, if your intention is to catch those situations where the target module isn’t present, then you should be specific and useModuleNotFoundError.

ImportError

Python raises theImportError exception for all the import-related issues that aren’t covered byModuleNotFoundError. This can happen for two main reasons:

  1. Animport module statement fails to load a module for a reason not covered byModuleNotFoundError.
  2. Afrom module import name statement fails to findname in the target module.

Now go ahead and run the followingimport statement to see theImportError exception in action:

Python
>>>fromsysimportnon_existingTraceback (most recent call last):...ImportError:cannot import name 'non_existing' from 'sys' (unknown location)

In this example, you try to import thenon_existing name from thesys module. Because the name doesn’t exist in this module, you get anImportError. You can quickly fix the problem by providing the correct target name.

Note: To dive deeper into how imports work in Python, check out thePython import: Advanced Techniques and Tips tutorial.

In real-world code, you can take advantage ofImportError orModuleNotFoundError to optionallyload different modules or libraries that provide a given functionality depending on the library availability.

For example, say you need to parse aTOML file and read its content. In this case, you can use the standard-library moduletomllib if you’re using Python3.11 or later. Otherwise, you should use the third-party librarytomli, which is compatible withtomllib.

Here’s how you can do this:

Python
try:importtomllib# Python >= 3.11exceptModuleNotFoundError:importtomliastomllib# Python < 3.11

The import in thetry clause targets the standard-library moduletomllib. If this import raises an exception because you’re using a Python version lower than 3.11, then theexcept clause imports the third-party librarytomli, which you need to install as an external dependency of your project.

Lookup Error Exceptions

Getting anIndexError when you perform indexing operations on asequence, or aKeyError when you look up keys in dictionaries, are also common issues in Python. In the following sections, you’ll learn about these two exceptions and when they can happen in your code.

IndexError

TheIndexError exception happens when you try to retrieve a value from a sequence using an out-of-range index:

Python
>>>colors=[..."red",..."orange",..."yellow",..."green",..."blue",..."indigo",..."violet",...]>>>colors[10]Traceback (most recent call last):  File"<input>", line1, in<module>colors[10]~~~~~~^^^^IndexError:list index out of range

In this example, you use10 as the index to get a value from yourcolors list. Because the list only has seven items, the valid indices go from0 to6. Your target index is out of range, and Python gives you anIndexError exception.

IndexError can be a frequent exception in Python, especially when you’re using dynamically generated indices. To fix the problem, you need to figure out which index your code is using to retrieve a value from the target sequence and then adjust the index range to correct the issue.

Note: In most situations, youwon’t use indices in Python loops. Because of this practice, the index error issue is less common in Python loops than in other programming languages where loops rely on indices.

If you can’t control the range of indices, then you can catch the exception in atryexcept block and take the appropriate recovery action.

You can also raise theIndexError exception in your own code. This exception can be appropriate when you’re creating custom sequence-like data structures. For example, say that you need to create a sequence-likestack:

Pythonstack.py
classStack:def__init__(self,items=None):self.items=list(items)ifitemsisnotNoneelse[]defpush(self,item):self.items.append(item)defpop(self):returnself.items.pop()def__len__(self):returnlen(self.items)def__getitem__(self,index):try:returnself.items[index]exceptIndexError:raiseIndexError(f"your stack only has{len(self)} items!")fromNone

In this example, you defineStack and provide the.push() and.pop() methods. The former method appends a new item to the top of the stack, while the latter removes and returns the item at the top of the stack.

Then, you have the.__len__()special method to support the built-inlen() function, which gives you the number of items in the stack.

Finally, you have the.__getitem__() method. This special method takes an index as an argument and returns the item at the input index. Thetryexcept block catches theIndexError exception and reraises it with a more specific error message. You don’t rely on the original message, which makes your code more focused.

KeyError

Similarly, when you try to get a non-existing key from adictionary, then you get aKeyError exception. This issue is also common in Python:

Python
>>>fruits={"apple":0.40,"orange":0.35,"banana":0.25}>>>fruits["grape"]Traceback (most recent call last):  File"<input>", line1, in<module>fruits["grape"]~~~~~~^^^^^^^^^KeyError:'grape'

In this example, you try to get thegrape key from thefruits dictionary and get aKeyError exception. In this case, the error message is pretty short. It only displays the name of the missing key.

Again, using dynamically generated keys can be the source of the problem. So, to correct the issue, you’ll need to check the generated and existing keys in your code. Alternatively, you can use the.get() method with an appropriate default value if that’s a suitable solution for your use case.

Finally, you can also raise aKeyError in your code. This could be helpful when you need to create adictionary-like class and provide a more descriptive error message for your users.

Name Errors:NameError

TheNameError exception is also pretty common when you’re starting with Python. This exception happens when you try to use a name that’s not present in your current namespace. So, this exception is closely related toscopes andnamespaces.

For example, say that you’re working in a REPL session. You’ve imported thesys module to use it in your current task. For some reason, you restart the interactive session and try to usesys without re-importing it:

Python
>>>sys.pathTraceback (most recent call last):  File"<input>", line1, in<module>sys.path^^^NameError:name 'sys' is not defined. Did you forget to import 'sys'?

Because you restarted the interactive session, all the names and modules that you imported before are gone. Now, when you try to use thesys module, you get aNameError.

Note that if the unknown name is after the dot in a qualified name, you won’t see aNameError. In this case, you’ll get anAttributeError exception instead, which you’ll learn about in the following section.

Object-Related Exceptions

You’ll find a few exceptions that can occur when working with Python classes, objects, and built-in types. The most common ones are the following:

In the following sections, you’ll learn when these exceptions happen and how to deal with them in your Python code.

TypeError

Python raises aTypeError exception when you apply an operation or function to an object that doesn’t support that operation. For example, consider calling the built-inlen() function with a number as an argument:

Python
>>>len(42)Traceback (most recent call last):  File"<input>", line1, in<module>len(42)TypeError:object of type 'int' has no len()

In this example, the argument tolen() is an integer number, which doesn’t support the function. Therefore, you get an error with an appropriate message.

In practice, you can catch theTypeError exception in your own code when you need to prevent a type-related issue. You can also raise the exception in your code to denote a type-related problem. For example, say that you want to write a function that takes an iterable of numbers and returns a list of squared values. You want to make sure that the function only accepts iterable objects.

In this situation, you can have a function like the following:

Python
>>>defsquared(numbers):...try:...iter(numbers)...exceptTypeError:...raiseTypeError(...f"expected an iterable, got '{type(numbers).__name__}'"...)fromNone...return[number**2fornumberinnumbers]...>>>squared([1,2,3,4,5])[1, 4, 9, 16, 25]>>>squared(42)Traceback (most recent call last):...TypeError:expected an iterable, got 'int'

In this example, your function uses the built-initer() function to check the input data. This function raises aTypeError exception if the provided input isn’t iterable. You catch this exception and reraise it but with a custom error message that adheres to your code’s purpose. Then, you build the list of squared values using alist comprehension.

ValueError

Similarly, Python raises theValueError exception when an operation or function gets an argument that has the right type but an inappropriate value:

Python
>>>float("1")1.0>>>float("one")Traceback (most recent call last):...ValueError:could not convert string to float: 'one'

In this example, you first use the built-infloat() function to convert a string to a floating-point number. The input string contains a numeric value, so the operation succeeds.

In the second example, you call the same function using a string that doesn’t represent a valid number and get aValueError exception. Note that the input argument is a string, which is the correct type of argument. However, the input string isn’t a valid numeric value, so you have the right type but the wrong value.

You can also useValueError in your Python code. This exception can be appropriate in different situations. For example, say that you need to write a class to represent rainbow colors. This class has seven allowed color names, which you can represent with strings:

Pythonrainbow.py
COLORS={"Red":{"Hex":"#FF0000","RGB":(255,0,0)},"Orange":{"Hex":"#FF7F00","RGB":(255,127,0)},"Yellow":{"Hex":"#FFFF00","RGB":(255,255,0)},"Green":{"Hex":"#00FF00","RGB":(0,255,0)},"Blue":{"Hex":"#0000FF","RGB":(0,0,255)},"Indigo":{"Hex":"#4B0082","RGB":(75,0,130)},"Violet":{"Hex":"#8B00FF","RGB":(139,0,255)},}classRainbowColor:def__init__(self,name="Red"):name=name.title()ifnamenotinCOLORS:raiseValueError(f"{name} is not a valid rainbow color")self.name=namedefas_hex(self):returnCOLORS[self.name]["Hex"]defas_rgb(self):returnCOLORS[self.name]["RGB"]

In this example, you first define aCOLORS constant that holds the rainbow colors and their correspondingHex andRGB representation.

Then, you define theRainbowColor class. In the classinitializer, you use a conditional to make sure that the input color name is one of the rainbow colors. If that’s not the case, then you raise aValueError because the color name is of the correct type but has the wrong value. It’s a string but not a valid color name.

Here’s how the class works in practice:

Python
>>>fromrainbowimportRainbowColor>>>color=RainbowColor("Gray")Traceback (most recent call last):...ValueError:Gray is not a valid rainbow color>>>color=RainbowColor("Blue")>>>color.name'Blue'>>>color.as_rgb()(0, 0, 255)

In this code snippet, when you try to pass a color name that’s not allowed, then you get aValueError. If the color name is valid, then the class works fine.

AttributeError

Another common exception that you’ll see when you work with Python classes isAttributeError. This exception occurs when the specified object doesn’t define theattribute ormethod that you’re trying to access.

Take, for example, yourRainbowClass from the previous section. This class has one attribute and two methods,.name,.as_hex(), and.as_rgb(). If you access them, then you’ll have a result according to what they do. However, say that you try to access a method called.as_hsl(). What would happen?

Here’s the answer:

Python
>>>fromrainbowimportRainbowColor>>>color=RainbowColor("Blue")>>>color.as_hsl()Traceback (most recent call last):...AttributeError:'RainbowColor' object has no attribute 'as_hsl'

BecauseRainbowColor doesn’t define the.as_hsl() method, you get anAttributeError that tells you the class doesn’t have an attribute that matches that name.

This error can be common in complex class hierarchies that define similar classes with slightly different interfaces. In this situation, you may think that a given class defines a given method or attribute, but that may not be the case. To fix the issue, you can take a look at the class definition or documentation to make sure that you only use the attributes and methods that the class defines.

You can skip theAttributeError exception by using the built-inhasattr() function:

Python
>>>ifhasattr(color,"as_hsl"):...color.as_hsl()...else:...print("Hmm, you can't call that.")...Hmm, you can't call that.

In this example, you usehasattr() to explicitly check if thecolor object has an attribute called"as_hsl".

You can also catch and raise theAttributeError exception in your custom classes. In practice, this exception can be pretty useful because Python encourages you to use a coding style based on handling exceptions calledEAFP (easier to ask forgiveness than permission).

In short, using this style means that you decide to handle errors and exceptions when they happen. In contrast, with theLBYL (look before you leap) style, you try to prevent errors and exceptions before they happen. That’s what you did in the example above.

So, instead of relying onhasattr(), you should write the above example as follows:

Python
>>>try:...color.as_hsl()...exceptAttributeError:...print("Hmm, you can't call that.")...Hmm, you can't call that.

This coding style is more direct. You go and call the desired method. If that fails with anAttributeError, then you perform alternative actions.

Finally, you’ll also get anAttributeError exception when you try to access an object that’s not defined in an already imported module:

Python
>>>importsys>>>sys.non_existingTraceback (most recent call last):...AttributeError:module 'sys' has no attribute 'non_existing'

Note that you don’t get an import error in this example. Instead, you get anAttributeError exception. That’s because the objects defined in a module become attributes of that module.

Arithmetic Error Exceptions

TheArithmeticError exception class is the base class for built-in exceptions that are related to three different types of arithmetic errors:

Of these three exceptions, the most common isZeroDivisionError. TheFloatingPointError is defined as a built-in exception, but Python doesn’t use it nowadays. In the following sections, you’ll learn about when theZeroDivisionError and theOverflowError exceptions may appear in your code.

ZeroDivisionError

Python raises theZeroDivisionError exception when a division’s divisor or right operand is zero. As a quick example, say that you need to write a function to compute the average grade of a group of students. In this case, you can come up with the following function:

Python
>>>defaverage_grade(grades):...returnsum(grades)/len(grades)...>>>average_grade([4,3,3,4,5])3.8

This function works okay when you use appropriate input data. But what would happen if you called the function with an empty list object? Here’s the answer:

Python
>>>average_grade([])Traceback (most recent call last):...ZeroDivisionError:division by zero

Because the input list is empty, thelen() function returns0. This return value produces aZeroDivisionError exception when the actual division occurs.

To fix the issue, you can catch the exception and present the user with a descriptive error message:

Python
>>>defaverage_grade(grades):...try:...returnsum(grades)/len(grades)...exceptZeroDivisionError:...raiseValueError(..."you should pass at least one grade to average_grade()"...)fromNone...>>>average_grade([])Traceback (most recent call last):...ValueError:you should pass at least one grade to average_grade()

In this updated version ofaverage_grade(), you catch theZeroDivisionError that an empty input list generates and raise aValueError with a user-friendly error message.

Finally, theZeroDivisionError exception also occurs when the right-hand operand on amodulo operation is zero:

Python
>>>42%0Traceback (most recent call last):  File"<input>", line1, in<module>42%0~~~^~~ZeroDivisionError:integer modulo by zero

The modulo operator returns the remainder of dividing two numbers. Because the division of the numbers is the first step to computing the remainder, you can get aZeroDivisionError if the right-hand operand is0.

OverflowError

TheOverflowError isn’t that common. Python raises this exception when the result of an arithmetic operation is too large, and there’s no way to represent it:

Python
>>>10.0**1000Traceback (most recent call last):  File"<input>", line1, in<module>10.0**1000~~~~^^~~~~OverflowError:(34, 'Result too large')

In this example, the number that results from the power operation is too high, and Python can’t represent it correctly. So, you get anOverflowError exception.

Iteration-Related Exceptions

Python has a few built-in exceptions that are closely related to iteration. TheRecursionError is related to recursive code and is what you can call a standard exception. Then you have theStopIteration exception, which Python internally uses to control the execution flow offor loops. This exception has an asynchronous counterpart calledAsyncStopIteration, which Python uses inasync for loops.

Note: TheAsyncStopIteration exception has the same semantic meaning as theStopIteration exception but for asynchronous loops. So, this exception won’t be covered in this tutorial.

In the following sections, you’ll learn about theRecursionError andStopIteration exceptions and how Python uses them.

RecursionError

A function that calls itself is known as arecursive function. These types of functions are the base of an iteration technique calledrecursion.

Note: To learn more about recursion, check out theRecursion in Python: An Introduction tutorial.

Consider the following toy function as an example of a recursive function:

Python
>>>defrecurse():...recurse()...

This function doesn’t follow the rules of recursion because it doesn’t have a base case that stops the repetition. It only has a recursive case. So, if you call the function, then you get aRecursionError exception:

Python
>>>recurse()Traceback (most recent call last):  File"<input>", line1, in<module>recurse()  File"<input>", line2, inrecurserecurse()  File"<input>", line2, inrecurserecurse()  File"<input>", line2, inrecurserecurse()  [Previous line repeated 981 more times]RecursionError:maximum recursion depth exceeded

Python will raise aRecursionError exception when the interpreter detects that the maximum recursion depth is exceeded. This may happen when your base case doesn’t work properly or when the required number of recursions for performing the computation exceeds the recursion limit.

Note: A recursion limit is necessary because every function call occupies memory on your system’scall stack, so it’s a way to control memory usage.

You can use thesys.getrecursionlimit() function to check your current recursion depth:

Python
>>>importsys>>>sys.getrecursionlimit()1000

The result of calling this function is a number representing how many times a recursive function can call itself in Python. If appropriate for your use case, you can also set a different recursion limit using thesys.setrecursionlimit() function.

StopIteration

Python raises aStopIteration exception when you call the built-innext() function on an exhaustediterator. Its purpose is to signal that there are no more items in the iterator. So, Python uses this exception internally to control iteration.

Consider the following toy example:

Python
>>>numbers_iterator=iter([1,2,3])>>>next(numbers_iterator)1>>>next(numbers_iterator)2>>>next(numbers_iterator)3>>>next(numbers_iterator)Traceback (most recent call last):  File"<input>", line1, in<module>next(numbers_iterator)StopIteration

In this example, you use the built-initer() function to create an iterator from a short list of numbers. Then, you callnext() repeatedly to consume the iterator. The fourth call to this function raises aStopIteration exception to signal that the iterator has no more items to retrieve.

Internally, Python uses this exception to terminatefor loops. In other words, when afor loop is iterating over an iterator, the loop stops when it gets theStopIteration exception. Because of this, it’s not common to see this exception in action. Note that Python’sfor loop callsnext() under the hood to perform the iteration.

In practice, you can use theStopIteration exception in your code as part of an implementation of theiterator protocol. This protocol consists of two special methods:

  1. .__iter__() is called to initialize the iterator. It must return an iterator object.
  2. .__next__() is called to iterate over the iterator. It must return the next value in the data stream.

When you provide these methods in a custom class, then your class supports iteration. To signal when the iteration must stop, you must raise theStopIteration exception in the.__next__() method.

Note: To learn more about iterators in Python, check out theIterators and Iterables in Python: Run Efficient Iterations tutorial.

To illustrate how to useStopIteration, say that you need to create a custom class that takes a list of values and creates an iterator over their squares:

Pythonsquares.py
classSquareIterator:def__init__(self,values):self.values=valuesself.index=0def__iter__(self):returnselfdef__next__(self):ifself.index>=len(self.values):raiseStopIterationsquare=self.values[self.index]**2self.index+=1returnsquare

In this class, the initializer takes a list of values as an argument. It also defines a reference index, which starts at0. The.__iter__() method returnsself, which is common practice when you’re using the iterator protocol like in this example.

In the.__next__() method, you check if the current index is greater than or equal to the number of values in the input list. If that’s the case, then you raise aStopIteration to signal that the iterator is exhausted. Next, you compute the square of the current value and return it as the method’s result.

Now you can use instances of this class in afor loop:

Python
>>>fromsquaresimportSquareIterator>>>forvalueinSquareIterator([1,2,3]):...print(value)...149

Your iterator works fine. It generates square values and supports iteration. Note that you don’t see theStopIteration exception happening. However, Python uses the exception internally to terminate the loop when the iterator is done.

File-Related Exceptions

When processing files in your Python code, there are several different problems you may face. Your code may try to create a file that already exists, access a non-existing file, run a file operation on a directory rather than a file, or have permission issues. Python has file-related exceptions that flag these situations.

Here are some of the most popular ones:

In the following sections, you’ll learn about these built-in exceptions and when they occur in Python.

FileExistsError

When you try to create a file or directory that already exists, Python raises the built-inFileExistsError exception.

To see this exception in action, say that you need to create a file in your working directory and write some text to it. However, you want to avoid replacing the file if it already exists. In this case, you can take advantage of theFileExistsError and write the following code:

Pythonhello.py
try:withopen("hello.txt",mode="x")asfile:file.write("Hello, World!")exceptFileExistsError:print("The file already exists")

In this example, you use the built-inopen() function to open a file calledhello.txt. The"x" mode means that you want to open the file for exclusive creation, failing if the file already exists.

Now go ahead and run thishello.py file from your command line:

Shell
$pythonhello.py

This command won’t issue any output. However, if you look at your working directory, then you’ll see a new file calledhello.txt with the text"Hello, World!" in it.

If you run the command again, then the result will be different:

Shell
$pythonhello.pyThe file already exists

This time, because thehello.txt file already exists, the file-creation code raises aFileExistsError exception, and theexcept clause prints an error message on the screen.

FileNotFoundError

Python raises theFileNotFoundError exception when a file or directory is requested but doesn’t exist in the target location. For example, say that you’ve accidentally removed thehello.txt file that you created in the previous section. When you try to read the file’s content, you get an error:

Python
>>>withopen("hello.txt",mode="r")asfile:...print(file.read())...Traceback (most recent call last):  File"<input>", line1, in<module>withopen("hello.txt",mode="r")asfile:^^^^^^^^^^^^^^^^^^^^^^^^^^^FileNotFoundError:[Errno 2] No such file or directory: 'hello.txt'

In this code snippet, you try to open thehello.txt file to read its content. Because you removed the file prior to this operation, your code fails with theFileNotFoundError exception.

To handle this issue, you can rewrite your code as in the following example:

Python
>>>try:...withopen("hello.txt",mode="r")asfile:...print(file.read())...exceptFileNotFoundError:...print("The file doesn't exist")...The file doesn't exist

Now, you use atryexcept block to handle theFileNotFoundError exception and prevent your code from breaking out.

PermissionError

Another common issue when processing files is when you try to access a file or directory without adequate access permissions. In this case, Python raises thePermissionError exception to let you know that you don’t have the required permissions.

For example, say you’re working on aUnix-like system, such as Linux or macOS. You want to update the content of the/etc/hosts file. In Unix-like systems, only the root user can modify this file. So, if you try to do your task using a different user, then you’ll get an error:

Python
>>>withopen("/etc/hosts",mode="a")asfile:...print(file.write("##"))...Traceback (most recent call last):  File"<input>", line1, in<module>withopen("/etc/hosts",mode="a")asfile:^^^^^^^^^^^^^^^^^^^^^^^^^^^PermissionError:[Errno 13] Permission denied: '/etc/host'

This error occurs because the file/etc/hosts is a system file. You need root permissions to modify this file. Your code tries to open the file for appending content without having the necessary permissions, which leads to aPermissionError exception.

Abstract Classes-Related Exception:NotImplementedError

Sometimes, you want to create a custom base class with a predefinedinterface from which your users can derive their own classes. This way, you ensure that the subclasses fulfill the required interface. In Python, you can do this using what’s known as anabstract base class (ABC).

Theabc module in the standard library providesABC class and other related tools that you can use to define custom base classes that define a specific interface. Note that you can’t instantiate ABCs directly. They’re intended to be subclassed.

When you start to create your ABCs, you’ll find that when you define methods, it’s a common practice to raise aNotImplementedError exception for those methods that the subclasses should implement but aren’t a strict requirement.

As an example, say that you want to create a class hierarchy to represent different birds, such as a duck, swan, penguin, and so on. You decide that all the classes should have the.swim() and.fly() methods. In this situation, you can start with the following base class:

Pythonbirds.py
fromabcimportABCclassBird(ABC):defswim(self):raiseNotImplementedError("must be implemented in subclasses")deffly(self):raiseNotImplementedError("must be implemented in subclasses")

In thisBird class, you inherit fromabc.ABC, which means you’re building an abstract base class. Then, you define the.swim() and.fly() methods, which raise theNotImplementedError exception with an appropriate error message.

Note: You may also importabstractmethod fromabc and decorate.swim() and.fly() with@abstractmethod. Python will raise an error if you instantiate any class with anabstract method.

Here’s an example of how you can derive concrete birds from the above class:

Pythonbirds.py
# ...classDuck(Bird):defswim(self):print("The duck is swimming")deffly(self):print("The duck is flying")classPenguin(Bird):defswim(self):print("The penguin is swimming")

In this example, you create theDuck class with the.swim() and.fly() methods. Then, you create thePenguin class, which only has a.swim() method because penguins can’t fly. You can use theDuck class normally. In contrast, thePenguin class will behave differently when you call its.fly() method:

Python
>>>frombirdsimportDuck>>>donald=Duck()>>>donald.swim()The duck is swimming>>>donald.fly()The duck is flying>>>skipper=Penguin()>>>skipper.swim()The penguin is swimming>>>skipper.fly()Traceback (most recent call last):...NotImplementedError:must be implemented in subclasses

In this code snippet, theDuck class works as expected. Meanwhile, thePenguin class raises aNotImplementedError when you call the.fly() method on one of its instances.

Assertion Errors:AssertionError

Python has a feature calledassertions that you can define using theassert statement. Assertions allow you to setsanity checks during the development of your code. Assertions allow you to test the correctness of your code by checking if some specific conditions remain true. This comes in handy while you’re testing and debugging your code.

Note: To dive deeper into theassert statement, check out thePython’s assert: Debug and Test Your Code Like a Pro tutorial.

The assert statement has the following syntax:

Python
assertexpression[,assertion_message]

Theexpression part is a condition that should be true unless you have a bug in your program. If the condition becomes false, then the assertion raises anAssertionError exception and terminates the execution of your program.

Assertions are useful for writing test cases. You can use them to check assumptions likepreconditions andpostconditions. For example, you can test whether an argument is of a given type, you can test the return value of a function, and so on. These checks can help you catch errors as soon as possible when you’re developing a program.

Note: You shouldn’t rely on assertions to check assumptions inproduction code because assertions are turned off when your code runs inoptimized mode using Python’s-O or-OO command-line options.

As an example, say that you’re in aPython coding interview. You’re asked to implement a function that tackles theFizzBuzz challenge, where you return"fizz" for numbers divisible by three,"buzz" for those divisible by five, and"fizz buzz" for those divisible by both three and five. You write a function like the following:

Pythonfizzbuzz.py
deffizzbuzz(number):ifnumber%3==0:return"fizz"elifnumber%5==0:return"buzz"elifnumber%15==0:return"fizz buzz"else:returnnumber

This function apparently covers all the possible scenarios. However, you decide to write a few basic tests to make sure that the function works correctly. You end up with the following code at the end of yourfizzbuzz.py file:

Pythonfizzbuzz.py
# ...if__name__=="__main__":assertfizzbuzz(9)=="fizz"assertfizzbuzz(10)=="buzz"assertfizzbuzz(15)=="fizz buzz"assertfizzbuzz(7)==7print("All tests pass")

In this code snippet, you’ve added some quick assertions to check whether your function returns the correct string with different input values. Now, you can run the test by executing the file from the command line:

Shell
$pythonfizzbuzz.pyTraceback (most recent call last):  File ".../fizzbuzz.py", line 26, in <module>    assert fizzbuzz(15) == "fizz buzz"           ^^^^^^^^^^^^^^^^^^^^^^^^^^^AssertionError

Wow! You’ve gotten anAssertionError exception, which means that some of the tests failed. When you look at the exception traceback, you note the assertion fails when you call the function with15 as an argument. This number is divisible by3 and by5, so the current order of your conditions is incorrect.

You must move the conditionnumber % 15 == 0 to the first position:

Pythonfizzbuzz.py
deffizzbuzz(number):ifnumber%15==0:return"fizz buzz"elifnumber%3==0:return"fizz"elifnumber%5==0:return"buzz"else:returnnumber# ...

The conditions first check whether the input number is divisible by3 and5. Now go ahead and run the file again:

Shell
$pythonfizzbuzz.pyAll tests pass

Great! All your tests pass. The function does its job correctly. That’s the power of theassert statement.

Finally, note that you shouldn’t explicitly raise theAssertionError exception in your code. Instead, you should let theassert statement raise this exception when the assertion’s condition fails. Additionally, you shouldn’t attempt to handle errors by writing code that catches theAssertionError exception because assertions can be disabled.

Interpreter Exit Exceptions

While writing Python code, you’ll find situations where you’ll need to exit or terminate a running application or program.

For example, if an error occurs while an app is running, you can decide to cleanly exit the app with an appropriateexit status, which can be helpful in command-line apps. Another example is when you’re testing some code that takes too long to run, or it’s somehow hanged. In this case, you’d like a quick way to terminate the code’s execution.

Python has the following exceptions that deal with these situations:

In general, your code shouldn’t be catching or handling these exceptions. Doing that can prevent you from exiting your program, making it impossible to quit from within the code or using the keyboard.

Note: Suddenly terminating a program with aSystemExit orKeyboardInterrupt may cause some undesired messy conditions in your system, such as leftover temporary files and open network or database connections.

You can use theatexit module from the standard library to manage how your code responds to this practice. This module allows you to register and unregister cleanup functions that will automatically execute upon normal termination of the Python interpreter.

In the following sections, you’ll learn when these exceptions can happen in your Python code. You’ll also write a couple of examples that illustrate their use.

SystemExit

Python raises theSystemExit exception when you call thesys.exit() function in your code. When you don’t handle the exception, the Python interpreter exits without printing an exception traceback:

Python
>>>importsys>>>sys.exit(0)$

In this example, you call thesys.exit() to terminate the Python interpreter. This call takes you back to your terminal session.

In practice, you can useSystemExit directly when you need to terminate an app. For example, say that you want to create a minimalCLI (command-line interface) app that mimics the basic functionality of the Unixls command, which lists the content of a given directory.

In this situation, you can write a script like the following:

Pythonls.py
importsysfrompathlibimportPathif(args_count:=len(sys.argv))>2:print(f"One argument expected, got{args_count-1}")raiseSystemExit(2)elifargs_count<2:print("You must specify the target directory")raiseSystemExit(2)target_dir=Path(sys.argv[1])ifnottarget_dir.is_dir():print("The target directory doesn't exist")raiseSystemExit(1)forentryintarget_dir.iterdir():print(entry.name)

This program processes the arguments provided at the command line, which are automatically stored in thesys.argv variable. The first item insys.argv is the program’s name. The second item should be the target directory.

The app should only accept one target directory, so theargs_count variable must be2 at most. If the app gets more than one target directory, then you print an error message and raise aSystemExit exception with an exit status of2. This indicates that the app exited after a failure.

Theelif branch checks whether the user has provided a target directory. If that’s not the case, then you print an error message to the user and exit the app, raising aSystemExit exception.

After checking the content ofsys.argv, you create apathlib.Path object to store the path to your target directory. If this directory doesn’t exist, then you inform the user and exit the app using theSystemExit exception again. This time, the exit status is1 to signal that the app faced an error during its execution. Finally, thefor loop lists the directory content, one entry per line.

On a Unix-like system, such as Linux and macOS, you can run the following command to check how the script works:

Shell
$pythonls.pyYou must specify the target directory$echo$?2$pythonls.py/home/etcOne argument expected, got 2$echo$?2$pythonls.py.hello.pybirds.pygrades.pygreeting.pyfizzbuzz.pyls.pymean.pystack.pysquare.pyrainbow.py$echo$?0

When you run the script with no argument, then you get a message telling you that you need to provide a target directory. When you use theecho command to check the exit code, represented by$?, you’ll see that it’s2. In the second example, you provide two target directories. Again, the app fails with an error message. Theecho command also returns2.

Finally, you run the script with the current working directory as an argument. In this case, you get the list of files that live in that directory. When you runecho, you get an exit status of0, which signals that the app’s execution was successful.

KeyboardInterrupt

TheKeyboardInterupt exception is somewhat different from other exceptions. Python raises this exception when the user intentionally presses theCtrl+C key combination during the execution of a program. This action interrupts a running program.

For example, say that you’re working on a piece of code that involves a loop. By error, the code falls into aninfinite loop. In this situation, you need a quick way to terminate the code’s execution. That’s when theCtrl+C key combination comes in handy.

Consider the following toy loop:

Python
>>>whileTrue:...print("Hello")...HelloHelloHelloHelloHelloHelloHelloHelloTraceback (most recent call last):...KeyboardInterrupt

This loop is intentionally written to be infinite. In practice, you can have real loops that run into infinite iteration because of a logical error. When you encounter this issue, you can press theCtrl+C keys to terminate the code’s execution. As a result, Python will raise aKeyboardInterrupt exception.

Finally, it’s important to note that you shouldn’t catch this exception in your code because this may prevent the interpreter from exiting.

Exception Groups

In Python 3.11 and greater, you’ll have theExceptionGroup andBaseExceptionGroup classes. You can use them when you need to raise multiple unrelated exceptions at the same time. The difference between these classes is thatBaseExceptionGroup extendsBaseException, whileExceptionGroup extendsException.

Note: To learn more about exception groups, check out thePython 3.11 Preview: Task and Exception Groups tutorial.

You can reach for these exceptions when anasynchronous program has several concurrent tasks that could fail at the same time. But in general, you will raise anExceptionGroup sparingly.

You can handle and raise exception groups as needed. Here’s how to catch an exception group with the associatedexcept* syntax:

Python
>>>try:...raiseExceptionGroup(..."several exceptions",...[...ValueError("invalid value"),...TypeError("invalid type"),...KeyError("missing key"),...],...)...except*ValueError:...print("Handling ValueError")...except*TypeError:...print("Handling TypeError")...except*KeyError:...print("Handling KeyError")...Handling ValueErrorHandling TypeErrorHandling KeyError

Theexcept* syntax allows you to catch individual exceptions on an exception group. This way, you can handle individual exceptions in specific ways.

Conclusion

You’ve learned about Python’sbuilt-in exceptions, which provide a quick and efficient way to handle errors and exceptional situations in your code. Now, you know the most commonly used built-in exceptions, when they appear, and how to use them in your exception-handling code. You also learned that you can raise these exceptions in your code.

In this tutorial, you’ve:

  • Learned whaterrors andexceptions are in Python
  • Understood how Python organizes thebuilt-in exceptions in aclass hierarchy
  • Explored the mostcommonly used built-in exceptions
  • Learned how tohandle andraise built-in exceptions in your code

This knowledge will help you efficiently debug your code because each exception has a specific meaning and use case. You’ll also be able to effectively handle and raise built-in exceptions in your code, which is a great skill for a Python developer.

Get Your Code:Click here to download the free sample code that you’ll use to learn about Python’s built-in exceptions.

Take the Quiz: Test your knowledge with our interactive “Python's Built-in Exceptions: A Walkthrough With Examples” quiz. You’ll receive a score upon completion to help you track your learning progress:


Python's Built-In Exceptions: A Walkthrough With Examples

Interactive Quiz

Python's Built-in Exceptions: A Walkthrough With Examples

In this quiz, you'll test your understanding of Python's built-in exceptions. With this knowledge, you'll be able to effectively identify and handle these exceptions when they appear. Additionally, you'll be more familiar with how to raise some of these exceptions in your code.

🐍 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

AboutLeodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He's a self-taught Python developer with 6+ years of experience. He's an avid technical writer with a growing number of articles published on Real Python and other sites.

» More about Leodanis

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:intermediatepython

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:

Python's Built-In Exceptions: A Walkthrough With Examples

Python's Built-In Exceptions: A Walkthrough With Examples (Sample Code)

🔒 No spam. We take your privacy seriously.


[8]ページ先頭

©2009-2025 Movatter.jp