0% found this document useful (0 votes)
33 views17 pages

CH 3 Exception Handling

Uploaded by

ujavaljani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views17 pages

CH 3 Exception Handling

Uploaded by

ujavaljani
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 17

Exception Handling in Python

Introduction

Exception handling in Python is a crucial part of writing robust and error-tolerant code. Python provides
a mechanism to deal with exceptions, which are unexpected events that can occur during the execution
of your program. These events can include things like division by zero, attempting to access a non-
existent file, or trying to use a variable that hasn't been defined.

The primary constructs for handling exceptions in Python are try, except, finally, and else.

Syntax Errors

Syntax errors, also known as parsing errors, are one of the most common types of errors in
programming. These errors occur when the code you write does not follow the correct syntax or
grammar of the programming language. In Python, a syntax error will prevent your program from
running and will be detected by the Python interpreter at the time of compilation.

Here are some common examples of Python syntax errors:

Mismatched Parentheses or Brackets: Forgetting to close parentheses, square brackets, or curly braces
will lead to a syntax error.

python

my_list = [1, 2, 3 # Missing closing square bracket

Unmatched Quotes: Not properly enclosing strings within single or double quotes.

python

message = 'Hello, this is a syntax error" # Mismatched quotes

Indentation Errors: Python relies on consistent indentation to define code blocks. Incorrect or
inconsistent indentation can lead to syntax errors.

python

def my_function():

print("This has incorrect indentation")

Missing or Extra Parentheses: Incorrect usage of parentheses in function calls or expressions.


python

result = (3 + 5) # Correct

result = (3 + 5 # Missing closing parenthesis

result = (3 + 5)) # Extra closing parenthesis

Incorrect Variable Names: Using invalid variable names or keywords.

python

3variable = 42 # Variable name cannot start with a digit

for = "loop" # Using a keyword as a variable name

Missing or Extra Commas: In lists, tuples, or function arguments, you should not have missing or extra
commas.

python

numbers = (1, 2, 3,) # Extra comma

function_call(1, 2 3) # Missing comma

When you encounter a syntax error, Python will typically provide an error message with information
about where the error occurred and what specifically is wrong with the code. This message is meant
to help you identify and fix the issue.

Correcting syntax errors is essential for your code to run successfully. Once you address these issues, you
can move on to dealing with other types of errors, such as logical errors and exceptions, to ensure your
program functions as intended.

Exceptions

Exceptions in Python are a mechanism for handling runtime errors or exceptional situations that may
occur during the execution of a program. When an exceptional event occurs, Python raises an exception,
which can be caught and handled by the programmer. Understanding and effectively handling exceptions
is crucial for writing robust and reliable code.

Here are some key concepts related to exceptions in Python:

Exception Types: Python has a variety of built-in exception types, such as ZeroDivisionError, TypeError,
FileNotFoundError, and KeyError, to name a few. Each exception type corresponds to a specific type of
error that can occur during program execution.

Raising Exceptions: You can raise exceptions explicitly in your code using the raise statement. This is
useful when you want to signal that a particular error condition has occurred.
Python

if x < 0:

raise ValueError("x should be a positive number")

Handling Exceptions: To handle exceptions, you use try and except blocks. The try block contains the
code where you expect exceptions to occur, and the except block handles these exceptions.

Python

try:

result = 10 / 0 # This raises a ZeroDivisionError

except ZeroDivisionError:

print("Division by zero is not allowed.")

Multiple except Blocks: You can have multiple except blocks to handle different types of exceptions.

python

try:

value = my_dict["key"] # This raises a KeyError

except KeyError:

print("Key not found in the dictionary.")

except Exception as e:

print(f"An error occurred: {e}")

else and finally Blocks: You can also use the else block to execute code when no exceptions are raised
in the try block. The finally block is executed regardless of whether an exception was raised. These
blocks are optional.

Python

try:

result = 10 / 2

except ZeroDivisionError:

print("Division by zero is not allowed.")

else:
print("No exceptions were raised.")

finally:

print("This will always execute, no matter what.")

Custom Exceptions: You can define custom exception classes by inheriting from the Exception class or
one of its subclasses. This allows you to create your own exception types to handle specific error
conditions in your application.

python

class MyCustomException(Exception):

pass

if something_went_wrong:

raise MyCustomException("Something went wrong in my code.")

# Handle MyCustomException in an appropriate `except` block.

Exception Propagation: If an exception is not caught in the current function, it will propagate up the
call stack until it is handled or until the program terminates. This means that exceptions can be caught
at higher levels in the program.

Python's exception-handling mechanism allows you to gracefully handle errors, provide informative
error messages, and take appropriate actions to recover from exceptional situations. This promotes
more robust and reliable software.

Built-in Exceptions

Python provides a wide range of built-in exceptions to handle different error conditions that might occur
during the execution of a program. Understanding these exceptions is crucial for effectively handling
errors in your code. Here are some of the most commonly used built-in exceptions:

SyntaxError: Raised when there is a syntax error in your code.

Indentation Error: A subtype of SyntaxError, raised when there are problems with the indentation of
your code.

NameError: Raised when a local or global name is not found.

TypeError: Raised when an operation or function is applied to an object of an inappropriate type.

ZeroDivisionError: Raised when you try to divide by zero.

IndexError: Raised when you try to access an index that is out of range for a sequence (e.g., a list or
string).
KeyError: Raised when a dictionary is accessed with a key that doesn't exist.

ValueError: Raised when a function receives an argument of the correct type but with an inappropriate
value.

FileNotFoundError: Raised when an attempt to open a file fails because the file does not exist.

IOError: A base class for I/O-related errors, including FileNotFoundError.

OSError: A base class for operating system-related errors.

ImportError: Raised when an import statement fails.

ModuleNotFoundError: A subtype of ImportError, raised when an imported module is not found.

ArithmeticError: A base class for arithmetic-related exceptions. Subtypes include ZeroDivisionError and
OverflowError.

ArithmeticError: A base class for arithmetic-related exceptions. Subtypes include ZeroDivisionError and
OverflowError.

AttributeError: Raised when an attribute reference or assignment fails.

Exception: A base class for all built-in exceptions.

KeyboardInterrupt: Raised when the user interrupts the program (e.g., by pressing Ctrl+C).

StopIteration: Raised when an iterator has no more items to return.

SystemExit: Raised when the sys.exit() function is called.

UnicodeError: A base class for Unicode-related exceptions. Subtypes include UnicodeEncodeError and
UnicodeDecodeError.

ValueError: Raised when a function receives an argument of the correct type but with an inappropriate
value.

EnvironmentError: A base class for exceptions related to file operations. Subtypes include IOError and
OSError.

NotImplementedError: Raised when an abstract method or function that should be overridden in a


subclass is not implemented.

These are just some of the most common built-in exceptions in Python. Python's standard library
includes many more exceptions to handle specific error situations. It's important to understand these
exceptions and use them appropriately in your code to make it more robust and error-tolerant. You can
also create custom exceptions by defining your own exception classes when you need to handle
application-specific error conditions.

Raising Exceptions

In Python, you can raise exceptions explicitly in your code when you encounter an error or an
exceptional situation using the raise statement. Raising exceptions allows you to signal that a particular
error condition has occurred, and you can then handle these exceptions in an appropriate try...except
block or propagate them up the call stack. Here's how to raise exceptions:
Basic Syntax:

To raise an exception, use the raise statement followed by the exception type and an optional error
message. The general syntax is as follows:

python

raise ExceptionType("Error message")

Here's an example:

Python

if something_went_wrong:

raise ValueError("An error occurred")

This code will raise a ValueError exception with the specified error message.

Custom Exceptions:

You can also raise custom exceptions by defining your own exception classes. To do this, create a class
that inherits from the Exception class or one of its subclasses, and then raise an instance of your
custom exception class.

python

class MyCustomException(Exception):

pass

if something_went_wrong:

raise MyCustomException("Something went wrong in my code")

Raising Predefined Exceptions:

Python provides many predefined exception types, such as ValueError, TypeError, NameError, and
more. You can raise these exceptions without defining a custom exception class.

python

if condition:

raise ValueError("A value error occurred")

Raising Exceptions with No Message:

You can raise an exception without providing an error message. The message is optional, and you can
access it through the args attribute of the exception object.
python

if condition:

raise ValueError # No message

Handling Raised Exceptions:

When you raise an exception, it can be caught and handled by using a try...except block. If an exception
is not caught in the current function, it will propagate up the call stack to higher-level code.

python

try:

if something_went_wrong:

raise ValueError("An error occurred")

except ValueError as e:

print(f"Caught an exception: {e}")

Exception Chaining:

You can raise a new exception while preserving the context of the original exception using the from
keyword.

python

try:

1/0

except ZeroDivisionError as e:

raise ValueError("An error occurred") from e

Raising exceptions is a useful technique for signaling errors and exceptional situations in your code, and
it allows you to provide informative error messages and facilitate proper error handling.

Handling Exceptions

Handling exceptions is a fundamental aspect of writing robust and reliable code in Python. Exception
handling allows you to gracefully deal with errors and unexpected situations, making your programs
more stable and user-friendly. You handle exceptions using try and except blocks. Here's how to handle
exceptions in Python:

Basic try...except Block:


The try block contains the code where you expect exceptions to occur. If an exception is raised within the
try block, the code in the corresponding except block is executed.

Python
try:
# Code that might raise an exception
except ExceptionType:
# Handle the specific exception
For example:

Python

try:
x = 10 / 0 # This raises a ZeroDivisionError
except ZeroDivisionError:
print("Division by zero is not allowed.")

Handling Multiple Exceptions:

You can have multiple except blocks to handle different types of exceptions.

Python
try:
value = my_dict["key"] # This raises a KeyError
except KeyError:
print("Key not found in the dictionary.")
except ValueError:
print("A value error occurred.")
except Exception as e:
print(f"An error occurred: {e}")

Generic Exception Handling:

You can use a more general except block without specifying the exception type to catch any exception
that's not handled by the specific except blocks.

Python
try:
# Code that might raise an exception
except SpecificException as e:
# Handle specific exception
except:
# Handle all other exceptions

The else Block:

The else block is optional and contains code that executes when no exceptions are raised in the try
block.

Python
try:
# Code that might raise an exception
except SpecificException as e:
# Handle specific exception
else:
# Code to execute if no exception occurs

The finally Block:

The finally block is also optional and contains code that always runs, regardless of whether an exception
was raised or not. It's often used for cleanup tasks like closing files or releasing resources.

Python
try:
# Code that might raise an exception
except SpecificException as e:
# Handle specific exception
finally:
# Code that always runs, regardless of exceptions

Exception Propagation:

If an exception is not caught in the current function, it will propagate up the call stack to higher-level
code, allowing you to handle the exception at an appropriate level in your program.

Python

def divide(x, y):


try:
result = x / y
except ZeroDivisionError:
print("Division by zero is not allowed.")
return result

try:
result = divide(10, 0)

except ZeroDivisionError:
print("Caught an exception in the calling code.")

Exception handling in Python is a powerful mechanism for dealing with errors and making your code
more reliable. By properly handling exceptions, you can provide informative error messages, take
corrective actions, and ensure that your program can gracefully recover from unexpected issues.

Need for Exception Handling

Exception handling is a critical aspect of programming in any language, including Python. It serves
several important purposes, making it an essential part of writing robust and reliable code:

Error Prevention: Exception handling helps prevent program crashes and unintended behavior due to
errors. Without proper error handling, even a minor mistake or unexpected situation can lead to a
program termination.

User-Friendly Applications: Exception handling allows you to provide informative error messages to
users when something goes wrong. Instead of showing cryptic error messages or crashing, your
application can gracefully inform users about what went wrong and what they can do to resolve the
issue.

Program Resilience: Exception handling makes your programs more resilient to unexpected conditions.
It enables your code to recover from errors and continue functioning, which is especially important for
long-running applications or services.

Debugging and Troubleshooting: When exceptions occur, the error messages and stack traces can be
valuable for debugging and troubleshooting issues in your code. They provide insight into the cause of
the problem, which can be critical for finding and fixing bugs.

Graceful Degradation: In some cases, your code might encounter errors that can be handled or worked
around. Exception handling allows you to gracefully degrade the functionality of your program instead
of failing completely. For example, if a web service is temporarily unavailable, your program can switch
to an alternative service.

Resource Management: Exception handling is crucial for releasing resources like files, database
connections, and network sockets. It ensures that these resources are properly closed and released,
even if an error occurs.

Structured Error Handling: Exception handling provides a structured and organized way to deal with
errors. It allows you to separate error-handling code from the main logic of your program, making your
code cleaner and more maintainable.

Security: Exception handling can be used to catch and handle security-related issues, such as invalid
input or authentication failures. By handling these issues appropriately, you can protect your
application from malicious attacks.

Robustness: Exception handling makes your code more robust by allowing you to anticipate and handle
a wide range of exceptional situations. This helps your application to handle edge cases and
unexpected conditions gracefully.

Custom Error Handling: You can create custom exceptions to handle specific error conditions in your
application, making it easier to manage and debug errors unique to your code.

In summary, exception handling is a fundamental programming technique that helps make your code
more reliable, user-friendly, and resilient. It allows you to anticipate and deal with unexpected
situations, recover from errors, and provide valuable information to users and developers when things
go wrong.

Process of Handling Exception

Handling exceptions in Python involves a structured process that helps you deal with errors gracefully.
The process typically consists of the following steps:
Try Block: The code that might raise an exception is placed inside a try block. This is where you enclose
the code that you anticipate may generate an exception.

Python

try:
# Code that might raise an exception

Exception Handling: You use one or more except blocks to catch and handle specific types of exceptions.
Each except block is responsible for handling a particular exception.

Python
except SomeException:
# Handle the specific exception
If the code in the try block raises an exception of the type specified in the except block, that block is
executed.

Multiple except Blocks: You can use multiple except blocks to handle different types of exceptions.
Python will execute the first except block that matches the raised exception.

Python
except SomeException:
# Handle the specific exception
except AnotherException:
# Handle another specific exception

Generic Exception Handling: You can have a more general except block without specifying the exception
type to catch any exception not handled by specific except blocks. However, it's essential to handle
specific exceptions whenever possible and use a generic except block sparingly.

Python
except SomeException:
# Handle the specific exception
except:
# Handle all other exceptions (not recommended for production code)

Exception Variables: When you catch an exception using an except block, you can optionally capture
information about the exception using an exception variable. This variable allows you to access details
about the exception, such as the error message.

Python
except SomeException as e:
print(f"Caught an exception: {e}")

else Block (Optional): The else block is optional and contains code that executes if no exceptions are
raised in the try block.

Python

except SomeException as e:
# Handle the specific exception
else:
# Code to execute if no exception occurs
finally Block (Optional): The finally block is also optional and contains code that always runs, regardless
of whether an exception was raised or not. It is often used for cleanup tasks like closing files or releasing
resources.

Python

except SomeException as e:
# Handle the specific exception
finally:
# Code that always runs, regardless of exceptions

Exception Propagation: If an exception is not caught in the current function, it propagates up the call
stack to higher-level code. This allows you to handle the exception at an appropriate level in your
program.

Python

def divide(x, y):


try:
result = x / y
except ZeroDivisionError:
print("Division by zero is not allowed.")
return result

try:
result = divide(10, 0)
except ZeroDivisionError:
print("Caught an exception in the calling code.")

The process of handling exceptions allows you to anticipate and deal with unexpected situations
gracefully, recover from errors, and provide valuable information to users and developers when things go
wrong. It makes your code more robust and user-friendly.

Catching Exceptions
Catching exceptions in Python involves using try and except blocks to handle specific types of exceptions
that may occur during the execution of your code. Here's how you can catch exceptions:

Identify the Code that Might Raise an Exception:


First, identify the part of your code where you expect an exception might occur. This is typically a section
of code that interacts with external data, files, user input, or network resources.

Enclose the Risky Code in a try Block:


Place the risky code inside a try block. The try block is where you monitor for exceptions.

Python

try:
# Code that might raise an exception
Handle Specific Exceptions with except Blocks:
Use except blocks to catch and handle specific types of exceptions. In each except block, specify the
exception type that you want to catch.

Python

except SpecificExceptionType:
# Handle this specific type of exception

For example, if you expect a FileNotFoundError, you can catch it like this:

Python

try:
file = open("non_existent_file.txt", "r")
except FileNotFoundError:
print("The file was not found.")

Handle Multiple Types of Exceptions:


You can have multiple except blocks to handle different types of exceptions in the same try block. Python
will execute the first except block that matches the raised exception.

python

try:
# Code that might raise an exception
except SpecificExceptionType:
# Handle this specific type of exception
except AnotherExceptionType:
# Handle another specific exception

Generic Exception Handling:


You can include a more general except block without specifying the exception type. However, it's
generally a good practice to handle specific exceptions when possible and use a generic except block
sparingly.

Python

try:
# Code that might raise an exception
except SpecificExceptionType:
# Handle this specific type of exception
except:
# Handle all other exceptions (not recommended for production code)

Use Exception Variables:


In the except block, you can optionally capture information about the exception using an exception
variable. This variable allows you to access details about the exception, such as the error message.

Python
except SpecificExceptionType as e:
print(f"Caught an exception: {e}")

Execute Code in the else Block (Optional):


You can include an optional else block that contains code to be executed if no exceptions are raised in
the try block.

Python

try:
# Code that might raise an exception
except SpecificExceptionType:
# Handle this specific type of exception
else:
# Code to execute if no exception occurs

Cleanup with the finally Block (Optional):


The finally block is also optional and is used for code that always runs, regardless of whether an
exception was raised or not. It is often used for cleanup tasks like closing files or releasing resources.

Python

try:
# Code that might raise an exception
except SpecificExceptionType:
# Handle this specific type of exception
finally:
# Code that always runs, regardless of exceptions

Catching exceptions in Python allows you to anticipate and gracefully handle unexpected situations,
recover from errors, and make your code more robust and user-friendly.

try...except…else clause

The try...except...else clause in Python is a control structure that allows you to handle exceptions
gracefully while also providing a block of code to execute when no exceptions are raised in the try block.
This is particularly useful when you want to separate error handling code from the main code flow.
Here's how it works:

try Block: The code that might raise an exception is placed inside the try block. This is where you enclose
the code that you anticipate may generate an exception.

Python

try:
# Code that might raise an exception
except Block: The except block is used to catch and handle specific types of exceptions. It comes
immediately after the try block. If an exception is raised within the try block, Python checks the except
blocks to determine if there is a matching exception handler.

Python

except SomeExceptionType:
# Handle this specific type of exception

You can have multiple except blocks to handle different types of exceptions.

else Block (Optional): The else block is optional and contains code to be executed if no exceptions are
raised in the try block. This block is executed after the try block has finished executing and before any
finally block (if present) is executed.

Python

except SomeExceptionType:
# Handle this specific type of exception
else:
# Code to execute if no exception occurs

The code inside the else block is executed when the try block runs to completion without raising an
exception.

Example:

Python

try:
x = int(input("Enter a number: "))
result = 10 / x
except ZeroDivisionError:
print("Division by zero is not allowed.")
except ValueError:
print("Invalid input. Please enter a number.")
else:
print(f"The result of the division is: {result}")

In this example, if the user enters a non-numeric value or the value 0, it will be caught by the respective
except block. Otherwise, if the user enters a valid non-zero number, the division will take place, and the
code in the else block will be executed.

The else block in a try...except...else structure is a way to isolate error-handling logic from the normal
code flow. It allows you to keep the error-handling code separate from the code that executes when no
exceptions occur, making your code more organized and readable.

Finally Clause
The finally clause in Python is used to specify a block of code that always executes, regardless of whether
an exception is raised or not in the preceding try and except blocks. This is particularly useful for
ensuring that certain cleanup or resource management tasks are performed consistently, even in the
presence of exceptions. Here's how the finally clause works:

try Block: The code that might raise an exception is placed inside the try block. This is where you enclose
the code that you anticipate may generate an exception.

Python

try:
# Code that might raise an exception

except Block (Optional): If an exception is raised within the try block, you can use one or more except
blocks to catch and handle specific types of exceptions.

Python

except SomeExceptionType:
# Handle this specific type of exception
You can have multiple except blocks to handle different types of exceptions.

finally Block: The finally block is used to specify a block of code that always runs, regardless of whether
an exception was raised or not. It is often used for cleanup tasks like closing files, releasing resources, or
ensuring that certain actions are performed.

Python

except SomeExceptionType:
# Handle this specific type of exception
finally:
# Code that always runs, regardless of exceptions

Example:

Python

try:
file = open("example.txt", "r")
content = file.read()
result = 10 / 2
except ZeroDivisionError:
print("Division by zero is not allowed.")
except FileNotFoundError:
print("File not found.")
else:
print("File read and division successful.")
finally:
file.close()
print("File closed, resources released.")
In this example, the try block attempts to open a file, read its content, and perform a division. If any
exceptions occur, they are caught and handled in the except block. Regardless of whether exceptions
occur, the finally block ensures that the file is closed and resources are released.

The finally clause is essential for situations where resource cleanup is required, regardless of whether an
exception is raised. It is also used to provide assurance that critical actions are performed, making your
code more robust and reliable.

You might also like