Nearby lessons
83 of 159Python - Finally Block
- Understand why clean-up code should live in a finally block instead of try or except
- Know that finally executes whether an exception is raised, handled, or neither
- Trace the execution order of try, except, else, and finally in every case
- Learn the one situation where the finally block is skipped - os._exit(0)
Why Do We Need the finally Block?
It is not recommended to maintain clean-up code (Resource Deallocating Code or Resource Releasing Code) inside the try block, because there is no guarantee that every statement inside the try block will always be executed.
Similarly, it is not recommended to maintain clean-up code inside the except block, because if there is no exception, then the except block will not be executed.
Hence, we require some place to maintain clean-up code that should be executed always, irrespective of:
- whether an exception is raised or not,
- whether the exception is handled or not handled.
Such a place is the finally block.
Purpose of the finally Block
- Maintain clean-up code.
- Release resources.
- Close files.
- Close database connections.
- Release network resources.
- Execute important statements before program termination.
General Syntax
Speciality of finally
The speciality of the finally block is:
- It will be executed whether an exception is raised or not raised.
- It will be executed whether the exception is handled or not handled.
Case 1 : No Exception
If no exception occurs inside the try block, the finally block is still executed.
Case 2 : Exception Raised and Handled
If an exception occurs inside the try block and a matching except block is available, the exception is handled first, and after that the finally block executes.
Case 3 : Exception Raised but Not Handled
If an exception occurs inside the try block but there is no matching except block, Python still executes the finally block before terminating the program.
Explanation
- In Case 1, no exception occurs, so the
exceptblock is skipped and onlytryandfinallyrun. - In Case 2,
10/0raises aZeroDivisionError, the matchingexceptblock handles it, and thenfinallyruns. - In Case 3,
10/0raises aZeroDivisionErrorbut only aNameErrorhandler exists. Thefinallyblock still runs, and only after it does Python terminate the program abnormally.
Comparison of the Three Cases
| Case | Exception | except Block | finally Block |
|---|---|---|---|
| Case 1 - No Exception | No | Skipped | Executed |
| Case 2 - Handled | Yes | Executed | Executed |
| Case 3 - Not Handled | Yes | Skipped | Executed |
Execution Flow
Program Starts
│
▼
Execute try Block
│
▼
Exception ?
┌────┴────┐
│ │
No Yes
│ │
▼ ▼
Skip or Matching
Run except?
except │
│ ┌────┴────┐
│ │ │
│ ▼ ▼
│ Handled Not Handled
│ │ │
└──────┼─────────┘
│
▼
Execute finally Block
│
▼
Program Ends
(After finally, an unhandled
exception still terminates the
program abnormally)
Key Observations
- The
finallyblock is mainly used for clean-up code. - It executes even if no exception occurs.
- It also executes after a handled exception.
- It even executes before an unhandled exception terminates the program.
- Resource releasing code should normally be written inside the
finallyblock.
Important Note - When finally is NOT Executed
There is only one situation where the finally block will not be executed.
It is when we use:
os._exit(0)
Whenever os._exit(0) is executed, the Python Virtual Machine (PVM) itself is shut down, so the finally block will not execute.
Example Using os._exit(0)
Here, 0 represents the status code, which indicates normal termination.
Because the PVM is shut down directly, finally is not printed.
else Block with try-except-finally
We can use the else block with try-except-finally blocks.
The else block will be executed if and only if there are no exceptions inside the try block.
Purpose of the else Block
- Execute code only when the
tryblock completes successfully. - Separate normal execution code from exception handling code.
- Improve readability of the program.
- Avoid writing normal statements inside the
tryblock unnecessarily.
Example
Case 1 : No Exception
If we comment line-1 (print(10/0)), then there is no exception inside the try block:
try else finally
Case 2 : Exception Occurs
If we do not comment line-1 (print(10/0)), then an exception occurs inside the try block:
try except finally
Comparison
| Situation | except | else | finally |
|---|---|---|---|
| No Exception | Skipped | Executed | Executed |
| Exception Occurs | Executed | Skipped | Executed |
Rules of try-except-else-finally
- Whenever we write a
tryblock, we must write either anexceptblock or afinallyblock. - An
exceptblock must always be associated with atryblock. - A
finallyblock must always be associated with atryblock. - We can write multiple
exceptblocks for onetryblock, but not multiplefinallyblocks. - Whenever we write an
elseblock, anexceptblock must also be present. - The order of the blocks is important:
try→except→else→finally. - We can define these blocks inside
try,except,else, orfinally— nesting is always possible.
Valid and Invalid Combinations
| Combination | Valid / Invalid |
|---|---|
| try only | ❌ Invalid |
| except only | ❌ Invalid |
| else only | ❌ Invalid |
| finally only | ❌ Invalid |
| try + except | ✅ Valid |
| try + finally | ✅ Valid |
| try + except + else | ✅ Valid |
| try + except + finally | ✅ Valid |
| try + except + else + finally | ✅ Valid |
- finally is meant for clean-up and resource-releasing code
- finally executes whether or not an exception is raised or handled
- The else block runs only when the try block completes without any exception
- os._exit(0) shuts down the PVM directly, so finally is the single case that does not run
- The correct block order is try, except, else, finally