Python Exception Handling Questions and Answers — Questions and Answers
Question 1: What is the correct order of execution for the blocks in a `try...except...else...finally` statement when no exception occurs within the `try` block?
- `try` -> `except` -> `finally`
- `try` -> `finally`
- `try` -> `else` -> `finally` (Correct answer)
- `try` -> `else`
Correct answer: `try` -> `else` -> `finally`
When a `try` block executes successfully without raising an exception, the `except` block is skipped. The `else` block is then executed because no error occurred. Finally, the `finally` block is always executed, regardless of whether an exception was raised or not.
Question 2: A developer needs to handle both `ValueError` and `TypeError` in the same way. Which of the following code snippets demonstrates the correct syntax for catching multiple specific exceptions in a single `except` block?
- except ValueError, TypeError:
- except [ValueError, TypeError]:
- except ValueError or TypeError:
- except (ValueError, TypeError): (Correct answer)
Correct answer: except (ValueError, TypeError):
To catch multiple exceptions in a single `except` clause, the exceptions should be specified as a tuple enclosed in parentheses. The other syntaxes are invalid for this purpose.
Question 3: When creating a custom exception class, what is the best practice for the base class from which it should inherit?
- Inherit from the `BaseException` class to catch all possible signals.
- Inherit from the `Exception` class to avoid catching system-exit events. (Correct answer)
- Do not inherit from any class; a standalone class is sufficient.
- Inherit from the `Error` class for semantic clarity.
Correct answer: Inherit from the `Exception` class to avoid catching system-exit events.
It is best practice to inherit from the built-in `Exception` class when creating custom exceptions. Inheriting from `BaseException` is discouraged because it can catch system-level exceptions like `KeyboardInterrupt` or `SystemExit`, which are not typically intended to be handled by application code.
Question 4: Consider the following code. What will be the final output printed to the console? ```python def check_value(): try: print("Start") raise ValueError print("After Raise") except ValueError: print("Caught") return "From Except" finally: print("Cleanup") print("End") print(check_value()) ```
- Start Caught Cleanup End From Except
- Start Caught Cleanup From Except (Correct answer)
- Start Caught From Except Cleanup
- Start After Raise End None
Correct answer: Start Caught Cleanup From Except
The `try` block starts and prints "Start". A `ValueError` is immediately raised, so "After Raise" is skipped. The `except ValueError` block is executed, printing "Caught". It then prepares to return "From Except". However, the `finally` block must execute before the function officially returns, so "Cleanup" is printed. After the `finally` block completes, the function returns the value from the `except` block, which is then printed. "End" is never reached because the return statement exits the function.
Question 5: Which of the following statements about the `raise` keyword in Python is true?
- Using `raise` by itself inside an `except` block is invalid syntax.
- The `raise` keyword can only be used with built-in exception types.
- Using `raise` by itself inside an `except` block re-raises the active exception, preserving its original traceback. (Correct answer)
- The `raise` keyword is used to create a new exception class.
Correct answer: Using `raise` by itself inside an `except` block re-raises the active exception, preserving its original traceback.
When `raise` is used without an exception object inside an `except` block, it re-raises the exception that was just caught. This is useful for logging an error before passing it up the call stack. This action preserves the original error's traceback, which is crucial for debugging.
Question 6: A function is designed to process a dictionary. If a specific key is not found, the function should stop its normal execution and signal this specific problem to the caller. Which built-in exception is most appropriate to `raise` in this scenario?
- IndexError
- ValueError
- KeyError (Correct answer)
- AttributeError
Correct answer: KeyError
`KeyError` is the specific exception raised when a dictionary key is not found. `IndexError` relates to sequences like lists when an index is out of bounds. `ValueError` is for when an argument has the right type but an inappropriate value. `AttributeError` occurs when an attribute reference or assignment fails.
What is the correct order of execution for the blocks in a `try...except...else...finally` statement when no exception occurs within the `try` block?