The finally keyword in Python is a crucial part of exception handling that ensures certain code executes no matter what happens — whether an error occurs or not. This concept is highly useful for releasing resources like files, network connections, or databases. In this tutorial, you’ll practice how to use the finally block effectively with multiple examples and real-world use cases.

1. Understanding the Python finally keyword
When working with try and except blocks, the finally block runs after all of them — regardless of whether an exception was raised or not. This guarantees that cleanup or closing operations are always performed. Here’s the basic structure:
try:
# Code that might raise an exception
print("Opening file...")
file = open("example.txt", "r")
content = file.read()
except FileNotFoundError:
print("Error: File not found.")
finally:
print("Closing file.")
file.close()
In this example, even if the file does not exist and a FileNotFoundError is raised, the finally block still runs to ensure that any open file handles are closed properly.
2. Why use finally in Python?
The main purpose of finally is to perform cleanup actions such as:
- Closing a file or database connection
- Releasing system resources
- Stopping background processes
- Logging completion messages
Without a finally block, you risk leaving resources open, leading to memory leaks or performance issues.
3. finally block with successful execution
Even when no exception occurs, the finally block will still execute. Let’s test it:
def divide_numbers(a, b):
try:
result = a / b
print(f"Result: {result}")
except ZeroDivisionError:
print("Cannot divide by zero!")
finally:
print("Execution finished.")
divide_numbers(10, 2)
Output:
Result: 5.0 Execution finished.
As shown, even if the division is successful, the finally statement always runs.
4. finally block when an error occurs
Let’s see what happens when an exception is thrown:
divide_numbers(10, 0)
Output:
Cannot divide by zero! Execution finished.
Here, finally executes even after an exception occurs, proving that it’s ideal for cleanup operations.
5. finally block without except
You can use finally even without an except block if you only need cleanup, like this:
try:
print("Running code...")
x = 10 / 0
finally:
print("Code finished.")
Output:
Running code... Code finished. Traceback (most recent call last): ... ZeroDivisionError: division by zero
Although the program crashes due to ZeroDivisionError, the finally message still appears before termination.
6. Nested try-finally blocks
You can also nest try and finally blocks to manage complex operations:
try:
print("Outer try started")
try:
print("Inner try started")
num = int("abc") # will raise ValueError
finally:
print("Inner finally executed")
except ValueError:
print("ValueError caught")
finally:
print("Outer finally executed")
Output:
Outer try started Inner try started Inner finally executed ValueError caught Outer finally executed
This demonstrates that even when an exception occurs inside a nested block, finally executes in both layers before the program ends.
7. Practical Example: File handling with finally
Here’s a real-world scenario where finally becomes useful — working with files:
def read_file(filename):
try:
file = open(filename, "r")
print(file.read())
except FileNotFoundError:
print("Error: File not found.")
finally:
print("Closing the file (if opened).")
try:
file.close()
except:
pass
read_file("data.txt")
This ensures that even if the file doesn’t exist, Python will still attempt to close the file safely without crashing.
8. Summary
- The
finallyblock always executes aftertryandexcept. - It’s essential for resource management and cleanup.
- You can use it even without
exceptto ensure certain code always runs. - It improves reliability and prevents resource leaks.
9. Practice Exercise
Try to create a program that opens a file, divides two numbers from user input, and always displays a message saying “Program Ended Safely” using finally.
try:
f = open("numbers.txt", "r")
a = int(input("Enter first number: "))
b = int(input("Enter second number: "))
print("Result:", a / b)
except FileNotFoundError:
print("numbers.txt file not found!")
except ZeroDivisionError:
print("Division by zero error!")
finally:
print("Program Ended Safely.")
This is how Python finally keyword ensures safe, predictable program execution — making your code more robust and reliable.