一、常见的异常
出现错误的原因:
•有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为 bug,bug 是必须修复的。
•有的错误是用户输入造成的,比如让用户输入 email 地址,结果得到一个空字符串,这种错误可以通过检查用户输入来做相应的处理。
•还有一类错误是完全无法在程序运行过程中预测的,比如写入文件的时候,磁盘满了,写不进去了,这类错误也称为异常,在程序中通常是必须处理的,否则,程序会因为各种问题终止并退出。
## NameError:name 'a' is not defined
# print(a)
## IndexError:list index out of range
# li = [1,2,3]
# print(li[6])
## KeyError: 'e'
# d = dict(a=1, b=2)
# print(d['e'])
## ZeroDivisionError:division by zero
# print(10/0)
# FileNotFoundError:
# with open('/mnt/pas','w') as f:
# f.write()
二、异常处理
• 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码;
• Python语言通常都内置了一套 try…except…finally… 的错误处理机制
1.单个错误类型处理(捕获异常,跳过继续执行):
- 用 try 来运行可能会出错的代码;
- 如果执行正确,则except 语句块不会执行;
- 如果执行错误,直接跳转至错误处理代码,即except语句块;
- 如果有 finally 语句块,不管try语句块内容是否正确,都会执行 finally语句块
示例:
import os
# 异常处理机制进行捕获异常; try....except....finally.....
def save_score(filename,score):
# 将可能出现问题的代码放在try语句中;
try:
# FileExistsError
os.mknod(filename)
print("创建文件%s成功" %(filename))
# 捕获异常, 当出现FileExistsError错误时, 忽略该错误, 不影响后面代码的执行;
except FileExistsError:
print("文件已存在")
with open(filename,'w') as f:
f.write(str(score))
print("write success")
score = 98
save_score('score.txt',score)
## 第一次运行
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
创建文件score.txt成功
write success
## 第二次运行
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
文件已存在
write success
2.多个错误类型处理:
• 错误有很多种类,如果发生了不同类型的错误,应该由不同的 except语句块处理。因此可以有多个 except 来捕获不同类型的错误。
try: ## 只执行一次try中的内容,遇到错误退出try,继续执行后面的语句
print("hello")
# print(a) # NameError
# l = [1,2,3]
# print(l[8]) # IndexError
# print(10/0) # Zero.....Error
# 捕获异常,
except (IndexError, NameError, ZeroDivisionError) as e:
print(e)
else:
# 如果没有捕获到异常, 则执行else语句
print("全部执行成功")
finally:
print("end")
## try 中无错误
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
hello
全部执行成功
end
## try 中有一个错误
# 例如:print(a) # NameError
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
hello
name 'a' is not defined
end
## try中出现多个异常时,只执行最先遇到的错误后退出
# 例如:print(a) # NameError
l = [1,2,3]
print(l[8]) # IndexError
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
hello
name 'a' is not defined
end
3.系统的异常类
• Python 的错误其实也是 class,所有的错误类型都继承自BaseException;
• 在使用except 捕获该类型的错误,还把其子类也“一网打尽”;
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
4.抛出自定义的异常
在引用之前,自定义异常类
class AgeError(Exception):
pass
age = int(input('Age:'))
if 0 < age < 150:
print(age)
else:
raise AgeError("年龄异常")
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
Age:155
Traceback (most recent call last):
File "/root/PycharmProjects/day10/01_常见异常.py", line 70, in <module>
raise AgeError("年龄异常")
__main__.AgeError: 年龄异常
5.exception官方案例
# 捕获ValueError异常;
while True:
try:
x = int(input('Num:'))
break
except ValueError as e:
print(e)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day10/01_常见异常.py
Num:s2
invalid literal for int() with base 10: 's2'
Num:bbba
invalid literal for int() with base 10: 'bbba'
Num:12
# 依次 遍历B, C, D三个异常
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
# 依次 遍历B, C, D三个异常
for cls in [B, C, D]:
try:
# raise B()
# raise C()
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
## 执行shell命令_检测异常
import sys
# sys.argv----命令后面跟的参数, 返回一个列表, 列表里面第一个元素是脚本名称;
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else:
# 没有捕获到异常, 执行的语句块;
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
[root@foundation10 day10]# chmod +x 02_执行shell命令_检测异常.py
[root@foundation10 day10]# ./02_执行shell命令_检测异常.py /mnt/passwd
/mnt/passwd has 60 lines
[root@foundation10 day10]# ./02_执行shell命令_检测异常.py /mnt/passd
cannot open /mnt/passd