exception handling in python

1. Problem

Whether developing large-scale programs or automating the developer's own daily chores, it is inevitable to encounter bugs, issues that were not considered before, system failures, and so on. At this time, it is necessary to keep the program as stable as possible, complete the basic cleanup, and provide clear clues of the problem stack and running logs, which is convenient for analysis and troubleshooting. Python's exception handling provides such a mechanism.

2. Processing flow

The basic syntax of exception handling in python is as follows:

try :
     <normal running program logic>
 except <exception type 1> :
     <exception type 1 handling>
 except <exception type...> :
     <exception type...handling>
 except <exception type N> :
     <exception type N processing>
 except :
     <unknown type type processing>
 else :
     <program logic that needs to be run in addition to exceptions>
 finally :
     <final processing and cleanup required for either normal or exception>

The python system provides some basic exception types, and each python package generally provides corresponding custom exceptions, and developers can also define their own exception types.

Exceptions can also be generated in python programs:

>>> raise NameError('true')
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    raise NameError('true')
NameError: true

2.1. Syntax exception: SyntaxError and NameError

Syntax exceptions are a common problem when running python code.

Sometimes the keyword used is wrong, or the variable is undefined, the system will report NameError. For example, in the following example, true is not the python keyword True , nor is it a defined variable:

>>> while true:
    print (0/0)
  
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    while true:
NameError: name 'true' is not defined

Sometimes it is a syntax problem, and the system will report a SyntaxError:

>>> if True
SyntaxError: invalid syntax

In this example, the ':' terminating character required by the conditional line is missing.

2.2. Basic system exception types

The python system provides some basic exception types, the following are some typical built-in system exceptions:

  • AssertError:  assertStatement error
  • EOFError: input input() encountered end of file
  • FloatingPointError: floating point number error
  • ImportError/ModuleNotFoundError: Error loading package
  • IndexError: index out of bounds
  • KeyError: The key to query does not exist in the dictionary, you can use the in keyword to check
  • NameError: cannot find local or global variable
  • NotImplementedError: The call does not define a method, which is a subclass of RuntimeError
  • OSError: System call error, such as I/O, or out of hard disk space
  • OverflowError: Numerical computation overflowed
  • RuntimeError: Error running
  • SystemError:
  • TypeError: wrong type
  • UnicodeError: unicode encoding and decoding errors
  • ValueError: Numeric type mismatch
  • ZeroDivisionError: divisor is 0

All python system built-in exceptions are available in the following documentation:

[python3]:https://docs.python.org/3/library/exceptions.html#bltin-exceptions

[python2]:https://docs.python.org/2/library/exceptions.html#bltin-exceptions

 2.3, custom exception type

A python program can define its own exception, so that the user of the program can do special processing for this exception. For example, a network connection error can be retried.

class Error(Exception):
     """Defines the base error class for this module . """ 
    pass

class InputError(Error):
     """Error input .

    Attributes:
        expression -- the input expression in error
        message -- the message of the error
    """
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class StateTransitionError(Error):
     """The system performed an incorrect state transition .

    Attributes:
        previous -- initial state
        next -- future state
        message -- state transition error message
    """
    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

2.4, get system error information

The exception types provided by the python system or other packages will provide error information. But sometimes it's not enough. For example, we need to get the access stack of the system, and we need to get some information about the running status of the system.

We can use the traceback package to get access stack information:

import traceback

def get_calltrace():
    try:
        a = 1
        b = 0
        c = a/b
    except:
        tb = traceback.format_exc()
    else:
        tb = "No error"
    finally:
        print (tb)

>>> get_calltrace()
Traceback (most recent call last):
  File "<pyshell#28>", line 5, in get_calltrace
ZeroDivisionError: division by zero

 Sometimes, you need to get more information from the system, you can call sys.exc_info():

import sys, traceback

def
get_calltrace(): try: a = 1 b = 0 c = a/b except: tb = traceback.format_exc() exc= sys.exc_info() else: tb = "No error" exc = None finally: print (tb) if exc: print (exc[0])      print (exc[1]) print (exc[2])

3, assert and parameter checking

 When we design programs, we often need to consider how to make the system more stable, help developers find problems as early as possible, and let end customers have the best experience.

  • assert: Mainly used for internal development, used to verify assumptions and help program design find problems as early as possible.
  • Parameter check: It is mainly used for external API development and is used to verify input parameters and help program design to find problems as soon as possible; the calling program must check whether the return value is wrong.

3.1、assert

An unchecked function will always fail, and the error message cannot be controlled:

def add(a, b):
    return a + b

>>> add('hello', 7)
Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    add('hello', 7)
  File "<pyshell#44>", line 2, in add
    return a + b
TypeError: must be str, not int

We can use assert to verify the validity of the call input and provide clear hints:

 def add_assert(a, b):
    assert isinstance(a, (int, float)), "a isn't numeric"
    assert isinstance(b, (int, float)), "b isn't numeric"
    return a + b

>>> add_assert('hello', 7)
Traceback (most recent call last):
  File "<pyshell#69>", line 1, in <module>
    add_assert('hello', 7)
  File "<pyshell#68>", line 2, in add_assert
    assert isinstance(a, (int, float)), "a isn't numeric"
AssertionError: a isn't numeric

3.2, parameter check

If a function is an open API, it needs to do input checking and return an error code to prompt the caller:

def add_validate(a, b):
    if not isinstance(a, (int, float)):
        return ("Fail", "a isn't numeric")
    if not isinstance(b, (int, float)):
        return ("Fail", "b isn't numeric")
    return ("OK", a+b)

>>> add_validate('hello', 7)
('Fail', "a isn't numeric")
>>> add_validate(5.0, 7)
('OK', 12.0)

4. Issues that need to be paid attention to

 Exceptions will always occur, and unknown exceptions must be caught and handled in the program, otherwise the system will crash.

When catching exceptions, you need to catch special exceptions first, and then catch common, unknown exceptions last.

Remember to release the allocated resources in the finally statement. Although python has garbage collection processing logic, not releasing resources in time is the main cause of memory leaks in python programs.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325236879&siteId=291194637
Recommended