What is exception handling?
Exception handling is a mechanism of programming languages designed to describe the program's response to runtime errors and other possible problems (exceptions) that may arise during the execution of the program and lead to the impossibility (meaninglessness) of further processing by the program of its basic algorithm.
Python code can generate an exception using the raise keyword. The exception object is specified after it. You can also specify an exception class, in which case the constructor without parameters will be automatically called. raise can throw only instances of the BaseException class and its heirs as exceptions, as well as (in Python 2) instances of old-type classes.
What can the try finally construct be used for without except
try:
# some code
finally:
# some code
If an error occurs in the try block, the finally block will still be executed and it will be possible to do a "cleanup" inside it, for example.
How to handle exceptions correctly in different ways
Except blocks are processed from top to bottom and control is passed to no more than one handler. Therefore, if it is necessary to handle exceptions that are in the inheritance hierarchy differently, first you need to specify handlers for less general exceptions, and then more general ones. This is also why bare except can only be the last one (otherwise SyntaxError). If you first place the handlers of more general exceptions, then the handlers of less general ones will simply be ignored.
What happens if the error is not handled by the except block
If none of the specified except blocks intercepts the raised exception, then it will be intercepted by the nearest external try/except block, which has the corresponding handler. If the program does not catch the exception at all, the interpreter terminates the program execution and outputs information about the exception to the standard sys.stderr error stream. There are two exceptions to this rule:
If an exception occurs in the object destructor, the program execution does not terminate, and the “Exception ignored” warning with information about the exception is output to the standard error stream.
When a System Exit exception occurs, only the program terminates without displaying information about the exception on the screen (does not apply to the previous paragraph, in the destructor, the behavior of this exception will be the same as the rest).
What to do if you need to intercept an exception, perform actions and raise the same exception again
To perform certain actions in the exception handler, and then pass the exception on, one level of handlers higher (that is, throw the same exception again), the raise keyword is used without parameters.
try:
1 / 0
except ZeroDivisionError:
# some logic
raise
What is exception chaining?
In Python 3, when an exception is raised in the except block, the old exception is stored in the context data attribute and if the new exception is not processed, information will be output that a new exception occurred during the processing of the old one ("During handling of the above exception, another exception occurred:"). You can also link exceptions into one chain or replace old ones with new ones. To do this, use the raise new_exclusion from old_exclusion or raise new_exclusion from None construction. In the first case, the specified exception is stored in the cause attribute and the suppress_context attribute (which suppresses the exception output from context) is set to True. Then, if the new exception is not handled, information will be displayed that the old exception is the cause of the new one ("The above exception was the direct cause of the following exception:"). In the second case, suppress_context is set to True and cause to None. Then when an exception is thrown, it will be replaced with a new one (although the old exception is still stored in context).
In Python 2, there is no concatenation of exceptions. Any exception thrown in the except block replaces the old one.
What is the else block for?
The else block is executed if no exceptions occurred during the execution of the try block. It is designed to separate the code that can cause an exception that should be handled in a given try/except block from the code that can cause an exception of the same class that should be intercepted at a higher level, and minimizes the number of statements in the try block.
What can be passed to the exception constructor
Exceptions can take any unnamed arguments as a constructor parameter. They are placed in the args data attribute as a tuple (an immutable list). Most often, a single string parameter is used, which contains an error message. In all exceptions, the str method is defined, which by default calls str(self.args). Python 2 also has a message attribute, in which args[0] is placed if len(args) == 1.
What are the exception classes
Basic:
- BaseException is the base class for all exceptions. Exception is the successor class of BaseException, the base class for all standard exceptions that do not indicate mandatory program termination, and all custom exceptions.
- StandardError (Python 2) is the base class for all built-in exceptions except StopIteration, GeneratorExit, KeyboardInterrupt and SystemExit.
- ArithmeticError is the base class for all exceptions related to arithmetic operations.
- BufferError is the base class for exceptions related to operations on the buffer.
- LookupError is the base class for exceptions related to an invalid collection key or index.
- EnvironmentError (Python 2) is a base class for exceptions related to errors that occur outside the Python interpreter. In Python 3, its role is performed by OSError.
Some of the specific standard exceptions are:
- AssertionError – condition failure in the assert statement.
- AttributeError - error accessing the attribute.
- FloatingPointError - operation error on floating-point numbers.
- ImportError - error importing a module or a name from a module.
- IndexError - invalid index of a sequence (for example, a list).
- KeyboardInterrupt - termination of the program by pressing Ctrl+C in the console.
- MemoryError – lack of memory.
- NameError – name not found.
- NotImplementedError - action not implemented. It is intended, among other things, to create abstract methods.
- OSError is a system error.
- OverflowError - the result of an arithmetic operation is too large to be represented.
- RuntimeError is a common runtime error that does not fall into any of the categories.
- SyntaxError - syntax error.
- IndentationError - SyntaxError subclass - invalid indentation.
- TabError is a subclass of IndentationError - mixed use of tab characters and spaces.
- SystemError is an uncritical internal interpreter error. If this exception occurs, you should leave an error report on the site bugs.python.org
- SystemExit is an exception that is generated by the sys.exit() function. Serves to terminate the program.
- TypeError - data type mismatch error.
- UnboundLocalError - NameError subclass - accessing a non-existent local variable.
- ValueError - generated when an object of the correct type is passed to a function or operation, but with an incorrect value, and this situation cannot be described with a more precise exception, such as IndexError.
- ZeroDivisionError - division by zero.
In which cases can SyntaxError be handled
A syntax error occurs when the Python parser encounters a piece of code that does not conform to the language specification and cannot be interpreted. Since, in the case of a syntax error in the main module, it occurs before the start of the program execution and cannot be intercepted, the tutorial for beginners in the Python documentation even separates syntax errors and exceptions. However, SyntaxError is also an exception that inherits from Exception, and there are situations when it can occur during execution and be handled, namely:
- syntax error in the imported module;
- syntax error in the code that is represented by a string and passed to the eval or exec function.
Can I create my exceptions
Yes. They must be heirs of the Exception class. It is customary to name exceptions so that the name of their class ends with the word "Error".
What are warnings for and how to create your own
Warnings are usually displayed in situations where erroneous behavior is not guaranteed and the program, as a rule, can continue to work, but the user should be notified of something. The base class for warnings is Warning, which inherits from Exception. The basic Warning inheritor class for user warnings is UserWarning.
What is the warning module for?
The warning module contains functions for working with warnings. The main one is the warn function, which accepts one mandatory message parameter, which can be either a message string or an instance of the Warning class or subclass (in this case, the category parameter is set automatically) and two optional parameters: category (by default – UserWarning) – warning class and stacklevel (by default - 1) – the level of nesting of functions, starting from which it is necessary to output the contents of the call stack (useful, for example, for wrapper functions to output warnings, where stacklevel=2 should be set so that the warning refers to the place where this function is called, and not the function itself).
I wish you success!
Top comments (0)