股市有风险,投资需谨慎,一赚二平七亏本。程序有异常,处理要当心,一试二捕三处理。
在运行Python
代码的时候,会在输出的时候打印一些你不愿意见到的一种叫做Traceback
信息,很多初学者看到那一堆信息,往往都会处于懵逼状态,脑中总会冒出一句,这都是些啥玩意。如果你是第一次看到它,也许你不知道它在告诉你什么。虽然Python
的Traceback
提示信息看着挺复杂,但是里面丰富的信息,可以帮助你诊断和修复代码中引发这种信息的原因,以及定位到具体哪个文件的哪行代码导致的,所以说学会看懂Traceback
信息是非常重要的。引发这种Traceback
的原因有语法错误和异常两种。
Python的语法错误是指在编写程序时,代码的书写不符合语言本身的规定和逻辑而引发的错误。常见的错误有类型错误,缩进错误,索引错误,命名错误等,相对来说,比较容易修正。
Python的异常是指在执行时检测到的错误。
1. 何为Traceback
Traceback
是Python
错误信息的报告。在其他编程语言中有着不同的叫法包括stack trace
,stack traceback
,backtrac
等名称, 在Python
中,用的术语是Traceback
。
当你的程序导致异常时,Python
将打印Traceback
以帮助开发者知道哪里出错了。
此错误输出包含诊断问题所需的所有信息。错误输出的最后一行一般会告诉你引发了什么类型的异常,以及关于该异常的一些相关信息。错误信息的前几行指出了引发异常的代码文件以及行数。
在上面的错误信息中,异常类型是Typeerror
,意思是say_hello()缺少了一个必要的位置参数:someone。
2. 常见的异常类型
Python自带的异常处理机制非常强大,提供了很多内置异常类,可向用户准确反馈出错信息。Python是面向对象语言,认为一切皆对象,所以异常也是对象。Python异常处理机制中的BaseException是所有内置异常的基类,但用户定义的类并不直接继承BaseException,所有的异常类都是从Exception继承,且都在exceptions模块中定义。Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。根据异常的来源主要分为两类,一类是Python的内置异常类,一类是用户自定义异常。
此处我们主要介绍一些常见的内置异常类型:
- Exception:常规错误的基类
- SyntaxError:Python 语法错误
- ValueError:传入无效的参数
- TypeError:对类型无效的操作
- NameError:未声明/初始化对象
- ZeroDivisionError:除(或取模)零 (所有数据类型)
- ImportError:无法引入模块或包
- AttributeError:对象没有这个属性
- IndexError:序列中没有此索引(index)
- 点击访问更多内置异常
3. 异常处理
异常处理工作由“捕获”和“抛出”两部分组成。“捕获”指的是使用 try ... except
包裹特定语句,妥当的完成错误流程处理。而恰当的使用 raise
主动“抛出”异常,更是优雅代码里必不可少的组成部分。
3.1 捕获
try:
# 被监控的可能引发异常的语句块
except Exception1 [as e]:
# 处理异常 Exception1 的语句块,as e是可选的,意思是将捕获的异常类实例化对象赋值给e
except Exception2 [as e]:
# 处理异常 Exception2 的语句块
...
except Exception [as e]:
# 处理其余异常的语句块,Exception类是所有Python异常类的父类
else:
# 没有任何异常的语句块
finally:
# 无论try中代码是否抛出异常都会执行的语句块
场景描述:用户输入两个数据,输出两个数的商
# quotient.py
try:
dividend = int(input("请输入一个被除数:"))
divisor = int(input("请输入一个除数:"))
print("{} / {} = {}".format(dividend, divisor, dividend / divisor))
except ValueError:
print("不合法的数值")
except ZeroDivisionError:
print("除数不能为零")
finally:
print("致词:试一试才知道")
3.2 抛出
如果在捕获异常之后要显示重复地抛出,特别是当你觉得系统给出的错误信息不足需要补充,或者需要抛出一些自定义的异常时,raise 语句能够帮助你做到这一点。
场景描述:接收一个用户输入,如果输入的内容包含数字之外的其它字符,则引发一个ValueError
# raise_exception.py
inputValue = input("请输入一个只包含数字的内容:")
if not inputValue.isdigit():
raise ValueError("不合法的数字组成")
3.3 自定义异常
实际开发中,有时候系统提供的异常类型不能满足开发的需求。这时候你可以通过创建一个新的异常类来拥有自己的异常类型。异常类继承自 Exception 类,可以直接继承,或者间接继承。
# #1. 用户自定义异常类型,大多数场景只要该类继承了Exception类即可
class TooLongError(Exception):
"this is user's Exception for check the length of name "
def __init__(self, length):
self.length = length
def __str__(self):
print("姓名长度是" + str(self.length) + ",超过长度了!")
# 2. 手动抛出用户自定义类型异常
def name_check():
name = input("enter your name:")
if len(name)>4:
raise TooLongError(len(name)) #抛出异常很简单,使用raise即可,但是没有处理,即捕捉
else :
print(name)
# 3. 调用函数,执行
name_check()