← Back to Python Course | Chapter 10: Exception Handling | Lesson 3 of 5

Python finally & else

else runs only when nothing went wrong, and finally always runs no matter what, like turning off the lights when you leave a room either way. They finish off a try block tidily.
Syntax
python
try:
    # risky code
except ExceptionType:
    # handle error
else:
    # runs if no error
finally:
    # always runs

The else Block

An else block attached to try/except runs only when the try block completed without raising any exception -- this keeps code that should run 'on success' clearly separated from the risky code being guarded, rather than tacking it onto the end of the try block itself.

Example: The else Block

python
try:
    result = 10 / 2
except ZeroDivisionError:
    print("Error")
else:  # runs only because the try block succeeded
    print("Success:", result)

The else Block Real Example

A typical use is opening a file in the try block and reading from it in the else block -- if opening fails, you don't want to accidentally attempt the read too, and separating them into try/else makes that guarantee explicit rather than implicit.

Example: The else Block Real Example

python
try:
    f = open("data.txt", "w")
    f.write("saved")
except OSError:
    print("Could not open file")
else:  # only reached if opening and writing above succeeded
    f.close()
    print("File written and closed")

The finally Block

The finally block runs no matter what happens -- whether the try succeeded, an exception was caught, or even if the exception wasn't caught at all -- which is why it's the standard place to release resources like closing a database connection or a file handle.

Example: The finally Block

python
try:
    print(10 / 2)
finally:  # runs whether or not an exception occurred
    print("This always runs")

Complete try-except-else-finally Flow

Combining try, except, else, and finally in one structure gives you four distinct phases: risky code, error handling, success-only follow-up code, and guaranteed cleanup -- each with a clear, separate responsibility instead of tangled conditional logic.

Example: Complete try-except-else-finally Flow

python
try:
    value = int("42")
except ValueError:
    print("Conversion failed")
else:
    print("Converted:", value)  # runs only on success
finally:
    print("Done")  # runs regardless

Return Values and finally

Even if a return statement executes inside the try or else block, Python still runs the finally block before the function actually returns to its caller -- this guarantees your cleanup code executes even when the function is exiting early via return.

Example: Return Values and finally

python
def safe_divide(a, b):
    try:
        return a / b
    finally:
        print("Cleanup runs even though we returned")  # finally still runs before returning

print(safe_divide(10, 2))
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assuming else runs after except, when it runs only if the try block raised no exception.
  2. Putting a return inside finally, which overrides the value returned by try and can swallow exceptions.
  3. Forgetting that finally runs even when the function returns early, so cleanup code there may run when you did not expect it.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.