Skip to content
Computer ScienceCBSE Class 12 · Exception Handling in Python

The finally Block: try-except-finally in Python (Class 12 Computer Science)

Updated 16 October 2026 · Fact-checked

A finally block is written at the end of a try statement, after every except (and else) block. Its statements always run: when try succeeds, when an exception is handled, and when it is not. In the last case Python runs finally and then passes the exception on. It is used for clean-up such as closing a file.

Whichever path the try statement takes, finally runs; if no except matches, the error is re-raised only after finally finishes.

Illustration drawn for QuestionBuddy.

Understand The finally Block

The try statement can end with an optional finally clause (NCERT 1.7). The complete order of clauses is:

try:
    risky statements
except SomeError:
    handler
else:
    runs only if try raised nothing (optional)
finally:
    always runs

finally must be the last clause, after all except blocks and the else block. A try can also have finally with no except at all (try...finally).

When does finally run? Always, whichever way control leaves the try statement:

  • the try block finishes normally: try → (else) → finally
  • an exception occurs and an except block handles it: part of try → except → finally
  • an exception occurs and no except block matches: part of try → finally → the exception is re-raised, so it travels to the caller, and if nothing handles it the program stops with a traceback. Statements after the try statement do not run in this case (NCERT 1.7.1: 'execution of the finally clause does not terminate the exception').
  • the try or except block executes return, break or continue: finally still runs before the function returns or the loop moves on. In a function, the value being returned is held while finally runs, so a print in finally appears before the caller prints the returned value.

Why use it? finally is the place for clean-up that must happen whatever goes wrong: closing a file, closing a database connection, or printing a closing message. NCERT notes that it is common practice to use finally with files so that the file object is always closed. (The with statement does the same job for files automatically, which you will meet in File Handling.)

Recovering and continuing. If the exception is handled by an except clause, the program continues after the finally block as usual. If it is not, finally gives you a last chance to tidy up, but it does not stop the error.

The syllabus line is 'handling exceptions using try-except-finally blocks', so expect output questions that ask exactly which messages appear, and in what order, with and without an exception.

The finally Block: key facts

Order of clauses
  1. 1.try
  2. 2.except (one or more)
  3. 3.else (optional)
  4. 4.finally (optional, always last)
try...finally with no except is also valid.
What runs in each case
No exceptiontry, else, finally
Handled exceptiontry (up to the error), except, finally
Unhandled exceptiontry (up to the error), finally, then the exception is re-raised
return, break or continue inside try/except: finally runs first
After an unhandled exception, statements after the try statement are skipped.
Typical uses of finally
  • closing a file: f.close()
  • closing a database connection: con.close()
  • a final message such as 'OVER AND OUT'
NCERT Program 1-6 prints a closing message from finally.
Return and finally
  1. 1.return in try
  2. 2.finally runs
  3. 3.value reaches the caller
Prints inside finally appear before the caller prints the returned value.

How to answer The finally Block questions

For output questions with finally, decide which of the three paths the code takes, then write the messages in order.

  1. 1Trace the try block until it ends or the first exception occurs.
  2. 2If there was no exception, run else (if present) and then finally.
  3. 3If there was an exception, look for a matching except. If found, run it and then finally, and continue after the statement.
  4. 4If no except matches, run finally and then stop: the exception is re-raised, so only an outer handler (or a traceback) follows.
  5. 5If return, break or continue happens inside try or except, run finally before carrying it out.
  6. 6Inside a function called from print(), write finally's output first and the printed return value after it.
  7. 7In programs, put clean-up (close, final message) in finally, not at the end of try, where it might be skipped.

The finally Block in real life

The idea, met in an everyday situation. Answer the question in your own words, then compare with the model answer. The one-line hook is what to remember.

Clean-up that must always happen

Suppose a library kiosk opens a file of member names, reads the first line, and converts the second line to the number of books issued; a clerk accidentally typed 'seven' instead of 7 in that file.

Write the code so the file is closed whether or not the conversion fails, and show the output for a file containing 'Week 1' and 'seven'.

Try it first, then show the solutionSolution
  1. The conversion is risky; the close must happen in every case, so it goes in finally.
  2. f = open('notes.txt', 'r')
    try:
        print(f.readline().strip())
        n = int(f.readline())
        print(n * 2)
    except ValueError:
        print('bad number')
    finally:
        f.close()
        print('closed', f.closed)
  3. int('seven\n') raises ValueError; the except prints its message; finally closes the file.

Answer: Week 1
bad number
closed True

Memory hook: finally is the last person out who always switches off the lights.

finally runs even when the error is not handled

Imagine an exam-hall app that must print 'Hall locked' at the end of every session, even if the program crashes because of a bug it did not expect.

What is printed by this code, and does 'Session over' appear?

Try it first, then show the solutionSolution
  1. try:
        seats = {'A1': 'Riya'}
        print(seats['B2'])
    except IndexError:
        print('bad seat number')
    finally:
        print('Hall locked')
    print('Session over')
  2. seats['B2'] raises KeyError, which except IndexError does not match. finally still runs and prints 'Hall locked'; then the KeyError is re-raised and the program stops.

Answer: Hall locked, then the program stops with KeyError: 'B2'; 'Session over' is not printed.

Memory hook: finally locks the door even while the alarm is ringing, but it does not switch the alarm off.

Tricks to remember The finally Block

Short memory aids. Say each one aloud once, then use it on a question the same day.

  • finally = no matter what

    Success, handled error, unhandled error, return, break: finally runs in every case.

    Use it when: Any 'will this print?' question about finally.

  • Last clause, last word

    finally is always written last and runs last in the try statement.

    Use it when: Order-of-clauses MCQs.

  • Tidy up, don't cover up

    finally tidies up but never hides an unhandled exception; the error carries on after it.

    Use it when: Unhandled-exception outputs.

  • Goodbye before the gift

    When a function returns from try, finally says goodbye before the caller opens the returned gift.

    Use it when: Order of output with return and finally.

The finally Block: solved examples

Ordered from board level to HOTS. Try each one before you open the solution.

Example 1: No exception · 1 mark · Very short answerBoard level

Write the output:

try:
    x = 20 // 4
    print('x =', x)
except ZeroDivisionError:
    print('zero')
finally:
    print('finished')
Try it first, then show the solutionSolution
  1. 20 // 4 = 5 works, so the except block is skipped.
  2. finally runs anyway.

Answer: x = 5
finished

Example 2: Handled exception · 2 marks · Short answerHarder board level

Write the output:

try:
    print('start')
    y = 7 / 0
    print('y =', y)
except ZeroDivisionError:
    print('cannot divide')
else:
    print('no error')
finally:
    print('cleanup')
print('after')
Try it first, then show the solutionSolution
  1. 'start' prints; 7 / 0 raises ZeroDivisionError, so the rest of try and the else block are skipped. (1 mark)
  2. except prints 'cannot divide', finally prints 'cleanup', and since the exception was handled, 'after' prints. (1 mark)

Answer: start
cannot divide
cleanup
after

Example 3: Unhandled exception · 2 marks · Short answerHarder board level

Predict what appears on the screen:

try:
    n = int('4x')
    print(n)
except ZeroDivisionError:
    print('zero')
finally:
    print('done')
print('next line')
Try it first, then show the solutionSolution
  1. int('4x') raises ValueError; the only handler is for ZeroDivisionError, so it is not handled. (1 mark)
  2. finally still prints 'done', and then the ValueError is re-raised; the program stops and 'next line' is never printed. (1 mark)

Answer: done, followed by the error ValueError: invalid literal for int() with base 10: '4x'

Example 4: finally with return · 2 marks · Short answerHarder board level

Predict the output:

def check(x):
    try:
        return 10 / x
    except ZeroDivisionError:
        return 'inf'
    finally:
        print('checked', x)
print(check(2))
print(check(0))
Try it first, then show the solutionSolution
  1. check(2): try returns 5.0, but finally runs first and prints 'checked 2'; then print shows 5.0. (1 mark)
  2. check(0): except returns 'inf'; again finally prints 'checked 0' before 'inf' is printed. (1 mark)

Answer: checked 2
5.0
checked 0
inf

Example 5: finally with continue and break · 2 marks · Short answerHOTS / competency

Predict the output:

count = 0
for v in [3, 0, 'a', 5]:
    try:
        r = 6 / v
    except ZeroDivisionError:
        continue
    except TypeError:
        break
    finally:
        count += 1
print(count)
Try it first, then show the solutionSolution
  1. 3: no error, finally adds 1. 0: ZeroDivisionError → continue, but finally still adds 1. (1 mark)
  2. 'a': TypeError → break, and finally adds 1 before the loop ends; 5 is never reached. (1 mark)

Answer: 3

Example 6: Case study: a report generator · 4 marks · Case-basedHOTS / competency

Suppose a teacher's program computes the average of marks stored in a list and always prints 'Report closed' at the end.
(i) Write avg_report(M) using try-except-finally that prints the average, prints 'No marks' if the list is empty, and prints 'Report closed' in every case. (2 marks)
(ii) Show the output for [72, 88, 95] and []. (1 mark)
(iii) What would happen for ['72', 88] if only ZeroDivisionError is handled? (1 mark)

Try it first, then show the solutionSolution
  1. (i)
    def avg_report(M):
        try:
            print('Average:', sum(M) / len(M))
        except ZeroDivisionError:
            print('No marks')
        finally:
            print('Report closed')
    avg_report([72, 88, 95])
    avg_report([])
  2. (ii) sum 255 / 3 = 85.0. For [], len is 0, so ZeroDivisionError is handled.
  3. (iii) sum(['72', 88]) raises TypeError, which is not handled: 'Report closed' is still printed by finally, then the TypeError stops the program.

Answer: (ii) Average: 85.0 / Report closed / No marks / Report closed (iii) 'Report closed' prints, then the program stops with TypeError.

Where students lose marks in The finally Block

The slips examiners see most often, and what to write instead.

  • Mistake: Leaving out finally's output when there is no exception

    finally runs on the success path too.

    Wrong working

    x = 5

    Right working

    x = 5
    finished

    Do this: Always add finally's output at the end of the try statement.

    Usually costs: 1 mark.

  • Mistake: Printing the lines after an unhandled exception

    After finally runs, an unhandled exception is re-raised and the program stops.

    Wrong working

    done
    next line

    Right working

    done
    ValueError: ... (program stops)

    Do this: Check whether an except clause really matches before continuing past finally.

    Usually costs: 1 mark.

  • Mistake: Putting finally before except

    finally must be the last clause; anything else is a SyntaxError.

    Wrong working

    try:
    ...
    finally:
    ...
    except ValueError:
    ...

    Right working

    try:
    ...
    except ValueError:
    ...
    finally:
    ...

    Do this: Remember the order try, except, else, finally.

    Usually costs: Half a mark.

  • Mistake: Printing the returned value before finally's output

    The caller receives the value only after finally has run.

    Wrong working

    5.0
    checked 2

    Right working

    checked 2
    5.0

    Do this: Run finally, then go back to the caller's print.

    Usually costs: 1 mark.

Exam tips

  • Learn the three paths (no error, handled error, unhandled error) as three lines of output order; most finally questions are one of them.
  • Use finally for f.close() in file programs written without with; it shows the examiner you know where clean-up belongs.
  • If an output question has an unhandled exception, write the finally output and then name the error, e.g. 'done, then ValueError'.
  • else is optional and sits before finally; it runs only when try raised nothing.
  • raise and assert are not in the 2026-27 syllabus, so finally questions are built only from built-in exceptions.

Practice questions on The finally Block

Write each answer on paper first. Open the hint only if you are stuck, and the answer only when you have finished.

  1. Q1 · 1 mark · MCQBoard level

    The finally block in Python is executed:
    (a) only when an exception occurs (b) only when no exception occurs (c) always (d) only when the exception is handled

    Hint

    No matter what.

    Answer

    (c) always

  2. Q2 · 1 mark · Very short answerBoard level

    Where must the finally clause be placed in a try statement?

    Hint

    Last clause.

    Answer

    At the end, after all the except blocks and the else block (if any).

  3. Q3 · 1 mark · Very short answerBoard level

    Write the output:

    try:
        print([1, 2, 3][1])
    except IndexError:
        print('I')
    finally:
        print('F')
    Hint

    Does index 1 exist?

    Answer

    2
    F

  4. Q4 · 2 marks · Short answerHarder board level

    Write the output for each input value v = '8' and v = 'eight':

    try:
        n = int(v)
    except ValueError:
        print('not a number')
    else:
        print('square', n * n)
    finally:
        print('bye')
    Hint

    else runs only when try succeeds.

    Answer

    For '8': square 64 / bye. For 'eight': not a number / bye.

  5. Q5 · 2 marks · Short answerHarder board level

    Write a function safe_avg(L) that returns the average of L, returns 0 if L is empty, and prints 'done' in a finally block. What does print(safe_avg([4, 6])) display?

    Hint

    finally prints before the caller prints.

    Answer
    def safe_avg(L):
        try:
            return sum(L) / len(L)
        except ZeroDivisionError:
            return 0
        finally:
            print('done')
    print(safe_avg([4, 6]))

    Output: done, then 5.0

  6. Q6 · 1 mark · Assertion-reasonHarder board level

    Assertion (A): Statements written after a try...finally statement are executed even when an exception raised in the try block is not handled.
    Reason (R): The finally block is executed whether or not an exception occurs.
    (a) Both A and R are true and R is the correct explanation of A. (b) Both A and R are true but R is not the correct explanation of A. (c) A is true but R is false. (d) A is false but R is true.

    Hint

    What happens to an unhandled exception after finally?

    Answer

    (d) A is false (the unhandled exception is re-raised after finally, so later statements do not run) but R is true.

  7. Q7 · 2 marks · Short answerHOTS / competency

    Predict the output:

    def f(n):
        try:
            if n < 0:
                return 'neg'
            print('pos')
        finally:
            print('end', n)
    print(f(-1))
    print(f(2))
    Hint

    What does f return when n is 2?

    Answer

    end -1
    neg
    pos
    end 2
    None

Test your recall

Answer in your head or on paper first, then open the card. Pulling an answer out of memory makes it stick far better than re-reading.

  1. 1.When does a finally block run?Show answer

    Always: with no exception, with a handled exception and with an unhandled one.

  2. 2.What happens to an unhandled exception after finally runs?Show answer

    It is re-raised; if nothing else handles it, the program stops.

  3. 3.Write the order of the clauses of a full try statement.Show answer

    try, except, else, finally.

  4. 4.Does finally run if try executes return?Show answer

    Yes, before the function actually returns.

  5. 5.Name a common use of finally.Show answer

    Closing a file (or a database connection) whatever happens.

  6. 6.Can a try have finally without except?Show answer

    Yes; try...finally is valid.

The finally Block: frequently asked questions

Does the finally block run if the exception is not handled?

Yes. Python runs the finally block first and then re-raises the exception. If no outer handler catches it, the program stops after the finally block's output.

What is the difference between else and finally in exception handling?

else runs only when the try block raised no exception. finally runs in every case, whether or not an exception occurred and whether or not it was handled.

Why is finally used when working with files?

So that the file is closed even if an error occurs while reading or writing it. NCERT notes this as common practice; the with statement achieves the same thing automatically.

Which NCERT section covers finally?

NCERT Class XII Computer Science Chapter 1, section 1.7 (Finally Clause) and 1.7.1 (Recovering and continuing with finally clause), with Programs 1-6 and 1-7.