I tried to summarize Python exception handling

Exception handling

Today I will explain about ** error **. It's a rudimentary content, but it's okay to write an error try ~ except, right? If you are, please refer to it. Also, if there is an error in the explanation, I would appreciate it if you could comment.

By the way, errors that occur in Python are roughly divided into two types. syntax error </ font> and exception </ font>.

Syntax error

This happens when you can determine that you are wrong before you run the program. For example, an error that occurs when you use a variable name that does not meet the identifier rules, the indentation is wrong, or the syntax is wrong anyway. Write ʻa [0]as ʻa [0}, write ʻif as ʻof ... (Have you done this? I have ...) I can't give you an example. Hmm. Simply put, syntax errors are grammatical mistakes that decrease as you practice writing programs. I will write an example for the time being lol

#Syntax error example
a = [1, 2, 3]
print(a[3})

output

    print(a[3})
             ^
SyntaxError: invalid syntax

exception

This is an error that occurs when the computer (interpreter?) Determines "Can't handle this?" While running the program. In a simple example


a = [1, 2, 3]
print(a[3])

output

      1 a = [1, 2, 3]
----> 2 print(a[3])

IndexError: list index out of range

Since the elements of the array exist only up to index number 2, an exception will naturally occur when trying to output ʻa [3] . I've shown ʻIndexError as an example of an exception here, but there are many more.

Catch the exception

Now, when you run the program, you may want to continue processing even if an exception occurs. In that case, use the familiar try ~ except. Let's prevent the program from stopping even if ZeroDivisionError appears due to exception handling.


a = 1
b = 0

try:
    print(a/b)
except ZeroDivisionError:
    print('You can't divide it by 0, right? I got a ZeroDivisionError')
finally:
    print('Division is difficult')

output

You can't divide it by 0, right? I got a ZeroDivisionError
Division is difficult

You can add finally after the last cleanup, as in the example above. This is executed last, whether or not an exception occurs, where processing is interrupted and terminated.

Catch multiple exceptions

ʻExcept` can be specified so that the tuple can catch multiple exceptions as follows:


try:
    a = int(input('a = '))
    b = int(input('b = '))
    print(a/b)
except (ValueError, ZeroDivisionError):
    print('I'm getting a Value Error or Zero Division Error')

Output 1

a = 1.5
I'm getting a Value Error or Zero Division Error

Output 2

a = 1
b = 0
I'm getting a Value Error or Zero Division Error

Name the exception

In addition, you can name the exception that occurs. In the following, I'm typing to raise a ValueError or ZeroDivisionError, but I'm catching the exception that occurred and naming it ʻER`.


try:
    a = int(input('a = '))
    b = int(input('b = '))
    print(a/b)
except (ValueError, ZeroDivisionError) as ER:
    print(f'{type(ER)}Is happening')

Output 1

a = 1.5
<class 'ValueError'>Is happening

Output 2

a = 1
b = 0
<class 'ZeroDivisionError'>Is happening

Please note that the name ʻER can only be used in the suite of ʻexcept. If you do the following, NameError will occur (because it's a big deal, let's catch this NameError as well).


try:
    a = int(input('a = '))
    b = int(input('b = '))
    print(a/b)
except (ValueError, ZeroDivisionError) as ER:
    pass

try:
    print(ER)
except NameError:
    print('What is ER?')

output

a = 1.5
What is ER?

Raise an exception with raise

You can also intentionally raise an exception with raise. However, you can only use subclasses or instances of the BaseException class here. (As we'll see later, most of the common exceptions are subclasses of this BaseException.)


def ErFunc(b: int) -> None:
    if b == 0:
        raise ZeroDivisionError        
b = 0
try:
    ErFunc(b)
except BaseException as ER:
    print(f'{type(ER)}Is occurring')

output

<class 'ZeroDivisionError'>Is occurring

Since the BaseException class is specified here, any derived class can be caught. Here the ZeroDivisionError is caught.

User-defined exception

Finally, you can also use classes to create user-defined exception classes. The following is a program that finds the sum of two single-digit natural numbers, but raises an exception when a negative number or a two-digit number is entered or when the sum becomes two digits. Both the ParameterRangeException class and the ReturnRangeException class are range-related classes, so they inherit from the RangeException class. Of course, it's okay to inherit from the standard built-in class ʻException` class.


class RangeException(Exception):
    pass

class ParameterRangeException(RangeException):
    pass

class ReturnRangeException(RangeException):
    pass

def add(a: int, b: int) -> int:

    if not 0 < a < 10:
        raise ParameterRangeException
    
    if not 0 < b < 10:
        raise ParameterRangeException
        
    if a + b > 10:
        raise ReturnRangeException
    else:
        return a + b

try:
    a = int(input())
    b = int(input())
    print(f'The sum of the two numbers is{add(a, b)}Deshi')
except ParameterRangeException as PRE:
    print(f'{type(PRE)}Is occurring. Formal argument is 1~It must be 9')
except ReturnRangeException as RRE:
    print(f'{type(RRE)}Is occurring. I have to make the return value 9 or less')
finally:
    print('That's all for the exception')

Output 1

1
8
The sum of the two numbers is 9.
That's all for the exception

Output 2

2
11
<class '__main__.ParameterRangeException'>Is occurring. Formal argument is 1~It must be 9
That's all for the exception

Output 3

5
7
<class '__main__.ReturnRangeException'>Is occurring. I have to make the return value 9 or less
That's all for the exception

Supplement

--The parent class for standard built-in exceptions provided by Python is the BaseException class. With this as a parent, there is a ʻExceptionclass, and there areValueError class and ʻIndexError class in the form inheriting this.

--When making a user-defined exception, do not put BaseException in the argument of ʻUserExceptionClass (). By design, the BaseException` class doesn't seem to assume that it will be inherited by user-defined exceptions.

--There is a ʻArithmeticError class as a child class of the BaseException class, but there are ʻOverflowError class and ZeroDivisionError class under this class. If you want to handle arithmetic errors, you can put ʻArithmeticError in the argument when creating a user-defined exception (any class below the ʻException class is OK).

Recommended Posts