Python中同样有异常处理的机制。我们可以捕获异常来做相应的处理,这样不会让我们的程序终止运行。
异常处理
我们来看一个最简单的错误处理
def main():
temp = input("age:")
try:
age = int(temp)
except:
print("invalid integer")
if __name__ == "__main__":
main()
结果如下:
age:qqq
invalid integer
异常被我们捕获了!!!是不是很酷!!!
def main():
age = 0
while age < 1 or age > 200:
temp = input("age:")
try:
age = int(temp)
except:
age = 0
if __name__ == "__main__":
main()
这样就可以让用户一直输入,直到输入合法的年龄为止。
上面的例子只是简单的使用了异常处理,如果碰到下面的情况,我们就很难区分是谁出错了!!!
def main():
try:
age = int(input("age:"))
f = open(input("fp:"))
except:
print("exception!")
if __name__ == "__main__":
main()
我们可以对错误细化:
def main():
try:
age = int(input("age:"))
f = open(input("fp:"))
except ValueError:
print("int exception!")
except IOError:
print("io exception!")
if __name__ == "__main__":
main()
这样是不是就比较完美了???
我们以后再看到错误是不是就没有那么可怕了???
但是这样还是没有那么完美!!!
下面的这种情况就会出现问题,因为有可能导致文件没有被关闭!
def main():
try:
f = open(input("fp:"), "w")
age = int(input("age:"))
f.close()
except ValueError:
print("int exception!")
except IOError:
print("io exception!")
if __name__ == "__main__":
main()
结果如下:
fp:test.txt
age:ksjfklj
int exception!
这样就会导致test.txt没有被关闭。
错误机制里面还有一个finally,它是无论如何都会被执行的,即使没有出现异常也会被执行的!这样一结合就比较完美了!
def main():
try:
f = open(input("fp:"), "w")
age = int(input("age:"))
except ValueError:
print("int exception!")
except IOError:
print("io exception!")
finally:
f.close()
print("finally")
if __name__ == "__main__":
main()
结果1:
fp:test.txt
age:123
finally
结果2:
fp:test.txt
age:afk
int exception!
finally
那么还有没有更高端的错误处理呢?有的有的!!!
def main():
file = None
try:
file = open(input("fp:"), "w")
age = int(input("age:"))
except ValueError as e:
print(e)
except IOError as e:
print(e)
finally:
if file is not None:
file.close()
print("finally")
if __name__ == "__main__":
main()
结果:
fp:test.txt
age:jdfklj
invalid literal for int() with base 10: 'jdfklj'
finally
我们的程序是不是马上变得高大上了?
Python中的异常继承体系
就拿我们的IOError和ValueError来说,它的继承关系是:
IOError = WindowsError -> Exception -> BaseException -> object
ValueError -> Exception -> BaseException -> object
这样我们就可以使用更简单的方式来处理异常:
def main():
file = None
try:
file = open(input("fp:"))
age = int(input("age:"))
except Exception as e:
print(e)
finally:
if file is not None:
file.close()
print("finally")
if __name__ == "__main__":
main()
结果1:
fp:jskj
[Errno 2] No such file or directory: 'jskj'
finally
结果2:
fp:test.txt
age:dkjklfjsd
invalid literal for int() with base 10: 'dkjklfjsd'
finally
这样是不是更加完美了???
那么我们就要仔细想一下了?为什么会这样呢?实际上这种效果是由于多态机制产生的。
object基类
我们一般不会直接使用object类,object类定义了Python中类的很多特性,比如__init__()、__del__()
函数等。
BaseException类
所有的异常都可以是基类错误,它里面定义了一些基本的错误。BaseException类是给所有Exception类添加特性的。
Exception类
所有的error都是从Exception类中继承而来的,所以Exception类是给我们程序员用的。
自定义异常
def mydiv(n1, n2):
if n2 == 0:
raise ValueError("divisor is 0")
return n1 / n2
def main():
try:
print(mydiv(2, 1))
print(mydiv(250, 0))
except Exception as e:
print(e)
if __name__ == "__main__":
main()
结果:
2.0
divisor is 0
我们自己定义的异常被抛出来了,是不是很酷!!!
在Python中建议使用异常处理,我们也可以自己定义异常处理类,因为Python中的错误很多!!!
我们可以一级一级的将我们的异常抛出,直到合理的地方再进行处理!