[Python-6] Python exception mechanism

1. What is the exception

During the running of the software program, it is very likely to encounter the problems just mentioned. We call them exceptions. The English is: Exception, which means exceptions. When encountering these exceptions, or called exceptions, how can we make the written program handle it reasonably and exit safely without the program crashing?

At work, the situation encountered by the program cannot be perfect. For example: the program wants to open a certain file, the file may not exist or the file format is wrong; the program is running, but the memory or hard disk may be full, etc.

1. Pseudo-code description exception mechanism

If we want to copy a file, in the absence of an exception mechanism, we need to consider various exceptions. The pseudocode is as follows:

In this way, there are two disadvantages:

  1. Put logic code and error handling code together!
  2. The exceptions that programmers themselves need to consider are more complicated, and the requirements for programmers themselves are higher!

In the above situation, if Python’s exception mechanism is used to handle the situation, the comparison is as follows:

The essence of the exception mechanism : when an exception occurs in the program, the program exits safely and continues to execute after processing

In python, many classes used to describe and handle exceptions are introduced, called exception classes. The exception class definition contains the information of this type of exception and the method of handling the exception. The following is a more complete display of the inheritance hierarchy of built-in exception classes in python :

Everything in python is an object, and exceptions are also handled in the form of objects . Process:

  1. Throwing an exception: When executing a method, if an exception occurs, the method generates an object representing the exception, stops the current execution path, and submits the exception object to the interpreter.
  2. Catch exception: After the interpreter gets the exception, it looks for the corresponding code to handle the exception

Two, try and except structure 

try...exceptis the most common exception handling construct. The structure is as follows:

try:
    被监控的可能引发异常的语句块
except  BaseException [as  e]:
    异常处理语句块
  1. tryBlocks contain code that may throw exceptions, and exceptblocks are used to catch and handle exceptions that occur.
  2. During execution, if tryno exception is thrown in the block, eceptthe block is skipped and the subsequent code is executed;
  3. During execution, if tryan exception occurs in the block, skip trythe subsequent code in the block and jump to the corresponding exceptblock to handle the exception; after the exception is handled, continue to execute the subsequent code.

Execution Sequence Encountered Exception

#测试简单的0不能做除数异常
try:
    print("step1")
    a = 3/0
    print("step2")
except BaseException as e:
    print("step3")
    print(e)
print("step4")
除数为0,遇到异常输出结果:

step1
step3
division by zero
step4

Enter a number in a loop, and if it is not a number, handle an exception; until it is entered 88, the loop ends.

while True:
    try:
        x = int(input("请输入一个数字:"))
        print("您入的数字是",x)
        if x==88:
            print("退出程序")
            break
    except:
        print("异常:输入的不是一个数字")
执行结果:
请输入一个数字:10
您入的数字是 10
请输入一个数字:abc
异常:输入的不是一个数字
请输入一个数字:88
您入的数字是 88
退出程序

Three, try...multiple except structures

The above structure can catch all exceptions, and it is very common in work. However, from the perspective of classical theory, it is generally recommended to try to catch as many exceptions as possible (in the order of first subclass and then parent class), and write exception handling code in a targeted manner. In order to avoid missing possible exceptions, it can be added at the end BaseException. The structure is as follows:

try:
    被监控的、可能引发异常的语句块
except  Exception1:
    处理Exception1的语句块
except  Exception2:
    处理Exception2的语句块
[...]
except  BaseException:
    处理可能遗漏的异常的语句块

 multiple exceptstructures

try:
    a = input("请输入被除数:")
    b = input("请输入除数:")
    c = float(a)/float(b)
    print(c)
except ZeroDivisionError:
    print("异常:除数不能为0")
except TypeError:
    print("异常:除数和被除数都应该为数值类型")
except BaseException as e:
    print(e)
    print(type(e))
执行结果:

请输入被除数:10
请输入除数:0
异常:除数不能为0

Four, try...except...else structure

try...except...elsestructure was added else块. If tryno exception is thrown in the block, elsethe block is executed. If tryan exception is thrown in the block, the block is executed except, the block is not executed else.

try...except...elseStructural Execution Test

try:
    a = input("请输入被除数:")
    b = input("请输入除数:")
    c = float(a)/float(b)
except BaseException as e:
    print(e)
else:
    print("除的结果是:",c)
发生异常的执行情况(执行except块,没有执行else):
请输入被除数:5
请输入除数:0
float division by zero

没有发生异常的执行情况(执行完try块后,执行else):
请输入被除数:10
请输入除数:5
除的结果是: 2.0

Five, try...except...finally structure

try...except...finallyIn the structure, finallythe block will be executed regardless of whether an exception occurs; it is usually used to release trythe resources allocated in the block.

try...except...finallyStructured Simple Test

try:
    a = input("请输入一个被除数:")
    b = input("请输入一个除数:")
    c = float(a)/float(b)
except BaseException as  e:
    print(e)
else:
    print(c)
finally:
    print("我是finally中的语句,无论发生异常与否,都执行!")
print("程序结束!")
执行结果如下:

请输入被除数:10
请输入除数:0
float division by zero
我是finally中的语句,无论是否发生异常都执行

When reading a file, finallyensure that the file resource is closed

try:
    f = open("d:/a.txt",'r')
    content = f.readline()
    print(content)
except BaseException as e:
    print(e)
finally:
    f.close()       #释放资源。此处也可能会发生异常。若发生异常,则程序终止,不会继续往下执行
print("step4")
发生异常的执行结果:

Traceback (most recent call last):
[Errno 2] No such file or directory: 'd:/a.txt'
  File "...mypro_exception/my01.py", line 8, in <module>
    f.close()       #释放资源。此处也可能会发生异常。若发生异常,则程序终止,不会继续往下执行
NameError: name 'f' is not defined
Process finished with exit code 1

Six, return statement and exception handling issues

Because returnit has two functions: end method operation and return value. We generally don't returnput it in the exception handling structure, but put it at the end of the method.

returnand the correct way to handle the exception structure

def test01():
    print("step1")
    try:
        x = 3/0
       # return "a"
    except:
        print("step2")
        print("异常:0不能做除数")
        #return "b"
    finally:
        print("step4")
        #return "d"
    print("step5")
    return "e"         
#一般不要将return语句放到try、except、else、finally块中,会发生一些意想不到的错误。建议放到方法最后。
print(test01())
执行结果:

step1
step2
异常:0不能做除数
step4
step5
e

7. Common exceptions 

  • SyntaxError:Grammatical errors
    int a =3 
        ^
SyntaxError: invalid syntax
  • NameError: Attempt to access an undeclared variable
    print(a)
NameError: name 'a' is not defined
  •  ZeroDivisionError: Division by 0 error (division by zero error)
    a = 3/0
ZeroDivisionError: division by zero
  •  ValueError: Value error
    float("abc")
ValueError: could not convert string to float: 'abc'
  • TypeError: type error
    123+"abc"
TypeError: unsupported operand type(s) for +: 'int' and 'str'
  •  AttributeError: Access a non-existing property of an object
a=100
a.sayhi()
AttributeError: 'int' object has no attribute 'sayhi'
  •  IndexError: Index out of bounds exception
a = [4,5,6]
a[10]
IndexError: list index out of range
  • KeyError: key of dictionary does not exist
a = {'name':"pig",'age':18}
a['salary']

KeyError: 'salary'
exception name illustrate
ArithmeticError Base class for all numerical calculation errors
AssertionError Assertion statement failed
AttributeError object does not have this property
BaseException Base class for all exceptions
DeprecationWarning Warning about deprecated features
EnvironmentError Base class for operating system errors
EOFError No builtin input, EOF marker reached
Exception Base class for general errors
FloatingPointError floating point calculation error
FutureWarning Warning about future semantic changes of constructs
GeneratorExit The generator (generator) has an exception to notify the exit
ImportError Failed to import module/object
IndentationError indentation error
IndexError There is no such index (index) in the sequence
IOError I/O operation failed
KeyboardInterrupt The user interrupts execution (usually by typing ^C)
KeyError The key does not exist in the map
LookupError Base class for invalid data queries
MemoryError Out of memory errors (not fatal to the Python interpreter)
NameError Object not declared/initialized (has no properties)
NotImplementedError methods not yet implemented
OSError operating system error
OverflowError Numerical operation exceeds maximum limit
OverflowWarning Old warning about autopromotion to long
PendingDeprecationWarning Warning about features being deprecated
ReferenceError Weak references attempt to access objects that have been garbage collected
RuntimeError generic runtime error
RuntimeWarning Warnings about suspicious runtime behavior
StandardError Base class for all built-in standard exceptions
StopIteration iterator has no more values
SyntaxError Python syntax error
SyntaxWarning Warning about suspicious syntax
SystemError General interpreter system errors
SystemExit 解释器请求退出
TabError Tab 和空格混用
TypeError 对类型无效的操作
UnboundLocalError 访问未初始化的本地变量
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeError Unicode 相关的错误
UnicodeTranslateError Unicode 转换时错误
UserWarning 用户代码生成的警告
ValueError 传入无效的参数
Warning 警告的基类
WindowsError 系统调用失败
ZeroDivisionError 除(或取模)零 (所有数据类型)

八、with上下文管理 

finally块由于是否发生异常都会执行,通常我们放释放资源的代码。其实,我们可以通过with上下文管理,更方便的实现释放资源的操作。

with上下文管理的语法结构如下:

with  context_expr [ as  var]:
    语句块

with上下文管理可以自动管理资源,在with代码块执行完毕后自动还原进入该代码之前的现场或上下文。不论何种原因跳出with块,不论是否有异常,总能保证资源正常释放。极大的简化了工作,在文件操作、网络通信相关的场合非常常用。

with上下文管理文件操作

with open("d:/bb.txt") as f:
    for line in f:
        print(line)
执行结果:
abc
def
ghi

九、traceback模块和生成异常日志

使用traceback模块打印异常信息 

import traceback
try:
    print("step1")
    num = 1/0
except:
    traceback.print_exc()
运行结果:

step1
Traceback (most recent call last):
  File "...mypro_exception/my01.py", line 7, in <module>
    num = 1/0
ZeroDivisionError: division by zero
Process finished with exit code 0

使用traceback将异常信息写入日志文件

#coding=utf-8
import traceback

try:
    print("step1")
    num = 1/0
except:
    with open("d:/a.log","a") as f:
        traceback.print_exc(file=f)

十、自定义异常类

程序开发中,有时候我们也需要自己定义异常类。自定义异常类一般都是运行时异常,通常继承Exception或其子类即可。命名一般以ErrorException为后缀。

自定义异常由raise语句主动抛出。

自定义异常类和raise语句

#测试自定义异常类
class AgeError(Exception):  #继承Exception
    def __init__(self,errorInfo):
        Exception.__init__(self)
        self.errorInfo = errorInfo
    def __str__(self):
        return str(self.errorInfo)+",年龄错误!应该在1-150之间"
############测试代码################
if __name__ == "__main__":   #如果为True,则模块是作为独立文件运行,可以执行测试代码
    age = int(input("输入一个年龄:"))
    if age<1 or age>150:
        raise AgeError(age)
    else:
        print("正常的年龄:",age)
执行结果:

输入一个年龄:200
Traceback (most recent call last):
  File "...mypro_exception/my10.py", line 16, in <module>
    raise AgeError(age)
__main__.AgeError: 200,年龄错误!应该在1-150之间

自定义异常类一般都是运行时异常,通常继承Exception或其子类即可。命名一般以ErrorException为后缀。

自定义异常由raise语句主动抛出。

Guess you like

Origin blog.csdn.net/m0_62735081/article/details/124798344