错误与异常

作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息。Python 有两种错误很容易辨认:语法错误和异常。

一.语法错误

语法错误又称解析错误,是在学习Python 时最容易遇到的错误:

while True
    print('hello world')
'''
 File "/Users/CLAY/Desktop/Python/demo.py", line 1
    while True
             ^
SyntaxError: invalid syntax
'''

这个例子指出True后面少了一个冒号:,解析器会输出出现语法错误的那一行,并显示一个“箭头”,指向这行里面检测到第一个错误,文件名和行号也会被输出,以便输入来自脚本文件时你能知道去哪检查。

二.异常

即使语句或表达式在语法上是正确的,但在尝试执行时,它仍可能会引发错误。 在执行时检测到的错误被称为异常,异常不一定会导致严重后果,但是,大多数异常并不会被程序处理,此时会显示如下所示的错误信息。

print(10 / 0) #这个表达式在语法上是没有错误的
'''
Traceback (most recent call last):
  File "/Users/CLAY/Desktop/Python/demo.py", line 1, in <module>
    print(10 / 0)
ZeroDivisionError: division by zero
'''

错误信息的最后一行告诉我们程序遇到了什么类型的错误,异常有不同的类型,而其类型名称将会作为错误信息的一部分中打印出来,这一行的剩下的部分根据异常类型及其原因提供详细信息。

常见异常类型

异常名称

描述

BaseException

所有异常的基类

Exception

常规错误的基类

StopIteration

迭代器没有更多的值

SystemExit

解释器请求退出

OverflowError

数值运算超出最大限制

ZeroDivisionError

除或取模运算的第二个参数为0

AttributeError

对象没有这个属性

KeyError

映射中没有这个键

IndentationError

缩进错误

ValueError

传入无效的参数

Warning

警告的基类

异常的处理

在python中可以用try/except来进行异常的处理

while True:
    try:
        x = int(input('请输入一个数字'))
        print(x)
        break
    except ValueError:
        print('您输入的不是数字,请再次尝试!')

try语句的工作原理:

  • 首先,执行 try 子句 (try 和 except 关键字之间的语句)。
  • 如果没有异常发生,则跳过 except 子句 并完成 try 语句的执行。
  • 如果在执行try 子句时发生了异常,则跳过该子句中剩下的部分。然后,如果异常的类型和 except 关键字后面的异常匹配,则执行 except 子句 ,然后继续执行 try 语句之后的代码。
  • 如果发生的异常和 except 子句中指定的异常不匹配,则将其传递到外部的 try 语句中;如果没有找到处理程序,则它是一个未处理异常,执行将停止并显示如上所示的消息。
  • 如果except后面不跟任何异常类型,就能捕捉所有的异常。

try/except还有可选语句else和finally

try:
	执行代码
except 异常类型 as异常名:
	发生异常时执行的代码
else:
	没有异常时执行的代码
finally:
	不管有没有异常都会执行的代码

抛出异常

程序员可以用raise语句强制抛出一个指定的类型
raise语法格式如下:

raise [Exception [, args [, traceback]]]

比如我们要求不能输入5以上的数字,否则就会抛出错误,代码如下:

x = 10
if x > 5:
    raise Exception('x不能大于5')
'''
Traceback (most recent call last):
  File "/Users/CLAY/Desktop/Python/demo.py", line 3, in <module>
    raise Exception('x不能大于5')
Exception: x不能大于5
'''

自定义异常

程序可以通过创建新的异常类来命名它们自己的异常,异常类继承自 Exception 类,可以直接继承,或者间接继承。

class MyError(Exception):
    pass
def myerror(a,b):
    if a>b:
        raise MyError('a不能大于b')
myerror(4,3)
'''
Traceback (most recent call last):
  File "/Users/CLAY/Desktop/Python/demo.py", line 6, in <module>
    myerror(4,3)
  File "/Users/CLAY/Desktop/Python/demo.py", line 5, in myerror
    raise MyError('a不能大于b')
__main__.MyError: a不能大于b  
'''

MyError是我们自己定义异常类型,如果不满足程序要求,就抛出异常。大多数异常都定义为名称以“Error”结尾,类似于标准异常的命名。