python的错误分语法错误和运行时错误,语法错误不多做介绍,本文针对运行时错误进行介绍,即异常处理!
异常
常见的异常有:除零异常、使用了未定义变量异常、变量转化出错异常等。程序运行时会提示“ZeroDivisionError: division by zero”、“NameError: name ‘spam’ is not defined”、“TypeError: Can’t convert ‘int’ object to str implicitly”等对应的信息。
异常处理
- 将异常捕获
while True:
try:
x = int(input("请输入一个数字:"))
break
except ValueError:
print("输入了不合法数字")
如果输入的不是数字,程序会产生异常,类型为ValueError。此程序将关键代码置于try模块,产生异常后,代码不会继续向下执行,而是抛出异常,except负责捕获异常,如果可以捕获的异常和产生的异常类型相同或者为其祖先类别,那么,异常在此处被捕获,然后被处理。
捕获异常可以一次定义多种类型,相当于拿着多个对付多种武器的盾牌在等待异常出现。样例如下:
except (RuntimeError, TypeError, NameError):
pass
还可以分类别捕获,不同类别异常不同方式处理,当然,一次只能有一个异常捕获程序被调用,异常匹配按顺序进行。
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
前两个异常捕获为精准类型捕获,最后一个全捕获,打印了异常信息之后,将异常继续抛给了上一层程序。
try-except组合还有一个成员可选–else。在try模块中没发生任何异常的时候,except必然也没有发生,else执行。如下:
try:
f = open("/usr/code/a.txt", 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
- 抛出异常
在没有能力处理此异常或者为了保护程序的健壮性,可以将异常抛出,被抛出的对象一定是异常的实例。
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
try代码块抛出一个异常,被except捕获,异常处理模块打印了日志之后,将此异常继续向上抛出。
- finally收尾执行
finally作为try-except组合的收尾模块,无论以上模块发生了什么操作,finally代码块都会被执行。比如以下样例:
def divide(x, y):
try:
result = x / y #1
except ZeroDivisionError:
print("division by zero!") #2
else:
print("result is", result) #3
finally:
print("executing finally clause") #4
1、函数调用时候,未发生异常,那么,执行顺序是1->3->4。
2、函数调用过程,发生了ZeroDivisionError异常,那么,执行顺序1->2->4
3、函数调用过程,发生了未被except捕获的异常,那么,执行顺序4->打印异常信息。
自定义异常
开发过程中,经常通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。
class MyExcept(Exception):
def __init__(self,value):
self.value = value
def __str__(self):
return "my except info:" + repr(self.value)
myExcept = MyExcept([1,2.3])
try:
raise(myExcept)
except MyExcept as e:
#print("捕获此异常")
raise
异常信息输入会自动调用方法__str__,可以对其进行重载。