Python小白到老司机,快跟我上车!基础篇(十五)
Posted coder-pig
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python小白到老司机,快跟我上车!基础篇(十五)相关的知识,希望对你有一定的参考价值。
异常与断言
1、异常
了解异常前,首先是区分「语法错误」与「运行时异常」,
- 语法错误是连编译器都过不了的错误,比如if语句后面漏掉了冒号(:)程序跑都跑不起来;
- 运行错误则是程序跑起来后,因为程序的业务逻辑问题引起的程序崩溃,比如除以0。
① Python中的常见异常
Exception类
因为是 所有异常类的父类
,又称 万能异常
,可以捕获任何异常!Python中常见的异常如下表所示:
异常 | 描述信息 |
---|---|
AssertionError | 断言语句失败 |
AttributeError | 尝试访问未知的对象属性 |
IndexError | 索引超出序列的范围 |
keyError | 字典中查找一个不存在的Key |
NameError | 尝试访问一个不存在的变量 |
OSError | 操作系统产生的异常,比如FileNotFoundError |
SyntaxError | Python语法错误 |
TypeError | 不同类型间的无效操作 |
ZeroDivisionError | 除数为0 |
IOError | 输入输出错误 |
ValueError | 函数传参类型错误 |
② 异常捕获
Python中为我们提供了两组语句用于异常捕获,try-expect-else
和 try-finally
。下面讲解下六种常见的玩法:
- 「1. try捕获了任何异常,直接丢给except后的代码块处理」,代码示例如下:
try:
result = 1 / 0
except:
print("捕获到异常了!")
运行结果如下:
捕获到异常了!
- 「2. 捕获特定类型」,代码示例如下:
try:
result = 1 / 0
except ZeroDivisionError:
print("捕获到除数为零的错误")
运行结果如下:
捕获到除数为零的错误
- 「3. 针对不同的异常设置多个except」,代码示例如下
try:
sum = 1 + '2'
result = 1 / 0
except TypeError as reason:
print("类型出错:" + str(reason))
except ZeroDivisionError as reason:
print("除数为0:" + str(reason))
运行结果如下:
类型出错:unsupported operand type(s) for +: 'int' and 'str'
- 「4. 对多个异常统一处理」,代码示例如下:
try:
result = 1 / 0
sum = 1 + '2'
except (TypeError, ZeroDivisionError) as reason:
print(str(reason))
运行结果如下:
division by zero
- 「5. 当没有检测到异常时才执行的代码块,可以用else」,代码示例如下:
try:
result = 4 / 2
except ZeroDivisionError as reason:
print(str(reason))
else:
print("没有发生异常,输出结果:%d" % result)
运行结果如下:
没有发生异常,输出结果:2
- 「6. 无论是否发生异常都会执行的一段代码块」,代码示例如下:
try:
result = 4 / 2
except ZeroDivisionError as reason:
print(str(reason))
else:
print("没有发生异常,输出结果:%d" % result)
finally:
print("无论是否发生异常都会执行~")
运行结果如下:
没有发生异常,输出结果:2
无论是否发生异常都会执行。
③ 异常抛出
Python为我们提供的都是异常都是在特定条件下才会触发的。而在一些特定的场景,某些操作可能会引起我们的业务异常,比如让用户输入一串手机号码,手机号码由一串0-9的数字构成,而如果用户输入了其他字符,显然是不合理的。我们可以通过正则对输入的手机号码进行校验,如果是手机号码就打印出来,不是的话则利用Python提供的 raise关键字
抛出一个 ValueError异常。代码示例如下:
import re
# 注:这段正则你只需要知道是用来匹配电话号码的,正则在爬虫那里会详细讲解
phone_compile =re.compile(r'^(0|86|17951)?(13[0-9]|14[579]|15[0-35-9]|17[01678]|18[0-9])[0-9]8$')
number = input("请输入一串手机号码:")
if phone_compile.match(number) is not None:
print("您输入的手机号码是:%s" % number)
else:
raise ValueError
运行结果如下:
请输入一串手机号码:123456787
Traceback (most recent call last):
File "F:/Project/Python/Book/Chapter 7/7_1_7.py", line 12, in <module>
raise ValueError
ValueError
④ 自定义异常
上面通过raise关键字显式的抛出了一个内置的ValueError异常。如果程序里除了这个号码验证还有邮箱验证,我们又抛出一个这样的异常的话,会不利于异常的定位,异常是哪个地方引起的?对此,我们可以自定义异常,根据不同的错误抛出对应的异常。我们自定义一个非手机号码异常,代码示例如下:
# 自定义异常
class PhoneNumberException(Exception):
def __init__(self, message):
Exception.__init__(self)
self.message = message
if __name__ == '__main__':
phone_compile = re.compile(r'^(0|86|17951)?(13[0-9]|14[579]|15[0-35-9]|17[01678]|18[0-9])[0-9]8$')
number = input("请输入一串手机号码:")
if phone_compile.match(number) is not None:
print("您输入的手机号码是:%s" % number)
else:
raise PhoneNumberException("非法的手机号码!")
运行结果如下:
请输入一串手机号码:1234
Traceback (most recent call last):
File "F:/Project/Python/Book/Chapter 7/7_1_8.py", line 19, in <module>
raise PhoneNumberException("非法的手机号码!")
__main__.PhoneNumberException
⑤ sys.exc_info()函数
除了前面介绍的获取异常信息的方式外,还可以通过 sys模块里的exc_info()函数
获得,使用代码示例如下:
import sys
try:
result = 1 / 0
except:
tuple_exception = sys.exc_info()
# 输出结果依次是:异常类,类示例,跟踪记录对象
for i in tuple_exception:
print(i)
运行结果如下:
<class 'ZeroDivisionError'>
division by zero
<traceback object at 0x000001E079360288>
2、断言
当 assert关键字
后面的判断条件为假的时候,程序自动崩溃并抛出AssertionErro异常。一般在测试程序的时候才会用到:需要确保某个条件为真程序才能正常工作的时候使用。
另外要和异常处理进行区分:
「异常处理」用于对程序发生异常情况的处理,以增加程序的健壮性和容错性,而「断言」则是用来检查非法情况,用于帮助开发者快速定位问题位置。
Python中关于断言assert的玩法有两种:
assert 判断条件
:如果判断条件为false,就raise一个 AssertionErrorassert 判断条件,异常描述
:如果判断条件为false,就raise一个 带描述信息的AssertionError
代码示例如下:
a, b = 1, 2
# 第一种断言用法
assert a > b
# 第二种断言用法
assert (a > b), ("a 并不比 b 大'".format(a = a, b = b))
运行结果如下:
Traceback (most recent call last):
File "F:/Project/Python/Book/Chapter 7/7_1_10.py", line 5, in <module>
assert a > b
AssertionError
Traceback (most recent call last):
File "F:/Project/Python/Book/Chapter 7/7_1_10.py", line 6, in <module>
assert (a > b), ("a 并不比 b 大'".format(a = a, b = b))
AssertionError: 1 并不比 2 大'
以上是关于Python小白到老司机,快跟我上车!基础篇(十五)的主要内容,如果未能解决你的问题,请参考以下文章