The try, except, and finally blocks in Python work together to manage errors and ensure cleanup actions are performed reliably.
try Block: Contains code that might raise an exception. If an exception occurs, execution immediately stops and jumps to the corresponding except block.
except Block: Handles specific exceptions caught from the try block. It allows you to respond gracefully to errors, such as printing a message or using a fallback value.
finally Block: Executes regardless of whether an exception occurred or not. It is ideal for cleanup tasks like closing files, releasing resources, or logging, ensuring these actions always happen, even if an error occurs or a return, break, or continue is used.
For example:
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found!")
finally:
file.close() # Ensures file is closed, even if an error occurredThe finally block runs after the try and except blocks, even if a return statement is encountered in try or except. This makes it a reliable place for critical cleanup.
I understand the concept of try: except: block or try: except: else: but I don't seem to understand purpose of the finally: block.Is there a difference between:
try:
*try something*
except:
*catch and handle error
finally:
*continue rest of the script*And:
try:
*try something*
except:
*catch and handle error
*continue rest of the script without 'finally' block*I suppose there must be some difference,but I can't find any
exception - What is the intended use of the optional "else" clause of the "try" statement in Python? - Stack Overflow
python - Order of execution in try except finally - Stack Overflow
For ... except ... finally - Ideas - Discussions on Python.org
Jump statement in try except finally block
Videos
The statements in the else block are executed if execution falls off the bottom of the try - if there was no exception. Honestly, I've never found a need.
However, Handling Exceptions notes:
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
So, if you have a method that could, for example, throw an IOError, and you want to catch exceptions it raises, but there's something else you want to do if the first operation succeeds, and you don't want to catch an IOError from that operation, you might write something like this:
try:
operation_that_can_throw_ioerror()
except IOError:
handle_the_exception_somehow()
else:
# we don't want to catch the IOError if it's raised
another_operation_that_can_throw_ioerror()
finally:
something_we_always_need_to_do()
If you just put another_operation_that_can_throw_ioerror() after operation_that_can_throw_ioerror, the except would catch the second call's errors. And if you put it after the whole try block, it'll always be run, and not until after the finally. The else lets you make sure
- the second operation's only run if there's no exception,
- it's run before the
finallyblock, and - any
IOErrors it raises aren't caught here
There is one big reason to use else - style and readability. It's generally a good idea to keep code that can cause exceptions near the code that deals with them. For example, compare these:
try:
from EasyDialogs import AskPassword
# 20 other lines
getpass = AskPassword
except ImportError:
getpass = default_getpass
and
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
else:
# 20 other lines
getpass = AskPassword
The second one is good when the except can't return early, or re-throw the exception. If possible, I would have written:
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
return False # or throw Exception('something more descriptive')
# 20 other lines
getpass = AskPassword
Note: Answer copied from recently-posted duplicate here, hence all this "AskPassword" stuff.