Python finally
Learn how Python's finally block guarantees
that important cleanup code runs whether an operation
succeeds or raises an exception.
Learning Objectives
By the end of this lesson, you will understand how
the finally block works and when it should
be used in real Python programs.
You will learn how to:
- Understand the purpose of
finally. - Use
try / except / finally. - Understand when
finallyexecutes. - Combine
elseandfinally. - Perform cleanup operations safely.
- Use
finallywith files and resources. - Understand
finallywithreturn. - Avoid common mistakes.
What Is finally?
The finally block is part of Python's
exception-handling system.
Its most important feature is that it normally runs whether an exception occurs or not.
A basic structure looks like this:
try:
# Code that might fail
except SomeException:
# Handle the exception
finally:
# Code that should run afterward
The finally block is commonly used
for cleanup work that should happen regardless
of whether the operation succeeded or failed.
Why Use finally?
Programs often acquire resources temporarily. Examples include:
- Opening a file
- Connecting to a database
- Opening a network connection
- Acquiring a lock
- Starting a temporary operation
- Creating temporary resources
Once the operation is finished, these resources may need to be released.
Even if something goes wrong, your program gets an opportunity to perform necessary cleanup.
Basic finally Syntax
The simplest form uses try followed by
finally.
try:
print("Starting operation")
finally:
print("Cleanup operation")
Starting operation Cleanup operation
Notice that there is no except block here.
Python allows try to be followed directly
by finally.
When No Exception Occurs
If the code inside try succeeds,
Python still executes finally.
try:
number = 10
print("Number:", number)
finally:
print("Operation finished.")
Number: 10 Operation finished.
The operation succeeded, but the cleanup section still executed.
When an Error Occurs
The finally block also runs when an
exception occurs.
try:
number = 10 / 0
finally:
print("Cleanup executed.")
Cleanup executed.
After the finally block executes,
the unhandled ZeroDivisionError can
continue upward and produce a traceback.
finally does not automatically
handle an exception. It executes cleanup;
an except block is what handles
the exception.
try / except / finally
The most common complete structure combines all three blocks.
try:
number = int("abc")
print(number)
except ValueError:
print("Invalid number.")
finally:
print("Program section finished.")
Invalid number. Program section finished.
- Python enters
try. - An exception occurs.
- Matching
excepthandles it. finallyexecutes.- The program continues after the structure.
else + finally
Python allows all three optional components to work together:
try:
number = int("25")
except ValueError:
print("Invalid input.")
else:
print("Conversion successful.")
finally:
print("Finished.")
Conversion successful. Finished.
The three blocks have different responsibilities:
- try: attempt the operation.
- except: handle an exception.
- else: run after successful execution.
- finally: perform final cleanup.
Cleanup Operations
Cleanup means returning your program or environment to an appropriate state after an operation.
Examples include:
- Closing a resource
- Releasing a lock
- Closing a connection
- Deleting temporary resources
- Writing final log information
- Resetting temporary state
try:
print("Processing data...")
except Exception as error:
print("Something went wrong:", error)
finally:
print("Cleaning up resources...")
The cleanup message is intended to represent work that should happen after the main operation.
Using finally with Files
Before Python's with statement became
the preferred way to manage files, developers commonly
used finally to make sure files were closed.
file = None
try:
file = open("students.txt", "r", encoding="utf-8")
data = file.read()
print(data)
except FileNotFoundError:
print("File not found.")
finally:
if file is not None:
file.close()
print("File operation finished.")
For ordinary file handling, prefer
with open(...). Python's context
manager automatically handles closing the file.
with open("students.txt", "r", encoding="utf-8") as file:
data = file.read()
print(data)
Understanding finally is still important
because the same cleanup principle applies to many
resources beyond simple file reading.
Resource Management
A resource is something your program temporarily acquires and should eventually release.
Examples include:
- Database connections
- Network connections
- Files
- Locks
- Temporary resources
Failing to release resources can cause problems such as resource leaks, locked files, connection exhaustion or unexpected application behavior.
Acquire → Use → Release
finally and return
The interaction between finally and
return is important.
The finally block executes before a
function actually returns.
def example():
try:
return "Returning from try"
finally:
print("Finally runs first.")
print(example())
Finally runs first. Returning from try
A return inside
finally can override a return
value or even suppress an exception.
This usually makes code confusing and
difficult to debug.
Nested finally
Exception-handling structures can be nested when complex resource management requires it.
try:
print("Outer try")
try:
print("Inner try")
finally:
print("Inner cleanup")
finally:
print("Outer cleanup")
Outer try Inner try Inner cleanup Outer cleanup
The inner finally executes when the inner
operation finishes, followed by the outer cleanup.
If your exception-handling structure becomes deeply nested, consider reorganizing the code into smaller functions.
Real-World Examples
Example 1 — Database Connection
A database application may need to close a connection after an operation.
connection = None
try:
connection = connect_to_database()
perform_query(connection)
except DatabaseError:
print("Database operation failed.")
finally:
if connection is not None:
connection.close()
Example 2 — Processing a Report
try:
print("Generating report...")
generate_report()
except Exception as error:
print("Report failed:", error)
finally:
print("Report process ended.")
Example 3 — Releasing a Lock
lock.acquire()
try:
update_shared_data()
finally:
lock.release()
Acquire a resource, perform the operation, and make sure the resource is released.
Common Mistakes
1. Thinking finally Handles Exceptions
It does not. finally performs final
cleanup. An except block handles a
matching exception.
2. Returning from finally
Avoid this because it can override previous return values and suppress exceptions.
3. Using finally Everywhere
Use it when there is meaningful finalization or cleanup work to perform.
4. Ignoring Better Resource Management Tools
For files and many other resources, Python's
with statement is usually clearer and
safer.
5. Putting Unrelated Code in finally
Keep the cleanup block focused on operations that should happen after the main operation.
finally is about guaranteed
finalization—not about hiding errors.
Practice Exercises
Try solving these exercises without looking at the examples above.
Exercise 1 — Basic finally
Create a try / finally program that
prints a message from both blocks.
Exercise 2 — Division
Create a division program that uses
except to handle zero and
finally to print a completion message.
Exercise 3 — Input Validation
Ask the user for an integer and use
try / except / finally.
Exercise 4 — File Cleanup
Open a file and use finally to ensure
the file is closed.
Exercise 5 — else + finally
Create a program that uses all four concepts:
try, except,
else and finally.
Exercise 6 — Return
Create a function with a return inside
try and observe when
finally executes.
Exercise 7 — Resource Cleanup
Design a small program that acquires a resource,
uses it, and releases it inside finally.
Mini Challenge — Safe File Processor
Build a small program that processes a text file while demonstrating proper exception handling and cleanup.
- Try to open a file.
- Read its contents.
- Handle
FileNotFoundError. - Display the contents when successful.
- Use
finallyfor cleanup. - Print a final completion message.
Starter Structure
file = None
try:
file = open("students.txt", "r", encoding="utf-8")
data = file.read()
print("File contents:")
print(data)
except FileNotFoundError:
print("The file could not be found.")
finally:
if file is not None:
file.close()
print("File processing finished.")
Modify the program so it counts the number of lines and words in the file. Then display a small report after successful processing.
Quick Knowledge Check
Test your understanding of Python's
finally block.
1. What is the main purpose of finally?
2. Does finally normally run when no exception occurs?
3. Does finally handle an exception by itself?
4. Which structure can contain try, except, else and finally?
5. What is a common use of finally?
6. Which statement is generally discouraged?
7. Which Python feature is usually preferred for managing files?
8. What does else do in try / except / else / finally?
9. Can try be followed directly by finally?
10. What is the key idea behind finally?
Lesson Summary
In this lesson, you learned how the
finally block works and why it is useful
for cleanup and resource management.
finally is used for finalization
and cleanup.
finally does not itself handle
exceptions.
try / except / finally is useful
when an operation needs both error handling
and cleanup.
else can be used for code that
should run only after successful execution.
finally is useful for releasing
resources such as connections and locks.
finally
because it can suppress earlier results
or exceptions.
with statement.
finally is about making sure
important finalization work gets a chance
to happen. It is especially valuable when
your program works with resources that must
be released safely.
You've reached the end!
You now understand how finally
works and how it fits together with
try, except and
else.