python异常处理


title: python异常处理
data: 2018-4-6
categories:

  • python
    tags:
  • python

try...except

有时候写程序的时候,会出现一些错误或异常,导致程序终止。例如,做除法时,除数为0,会引起一个ZeroDivisionError

a=10
b=0
c=a/b
print("done")

运行结果:

Traceback (most recent call last):
...
ZeroDivisionError: division by zero

发现程序因为 ZeroDivisionError 而中断了,语句 print("done") 没有运行。为了处理异常,使用 try...except,更改代码:

a=10
b=0
try:
    c=a/b
    print(c)
except (ZeroDivisionError, TypeError) as e:
    print(e)
print("done") 

运行结果:

division by zero
done

这样程序就不会因为异常而中断,从而 print("done") 语句正常执行。

把可能发生错误的语句放在 try 模块里,用 except 来处理异常。except 可以处理一个专门的异常,也可以处理一组圆括号中的异常,如果 except 后没有指定异常,则默认处理所有的异常。每一个 try,都必须至少有一个 except

处理一组异常可以这样写(其中e代表异常的实例):

try:
    pass
except (IOError, ZeroDivisionError) as e:
    print(e)

Python 常见的标准异常类

异常名称 描述
Exception 所有异常的基类
AttributeError 特征引用或者赋值失败时引发的
IOError 试图打在不存在的文件(包括其他情况)
IndexError 使用序列中不存在的索引
KeyError 使用映射中不存在的键
NameError 找不到名字(变量)
SyntaxError 在代码为错误形式时引发
SystemExit 系统异常退出
TypeError 在内建操作或者函数应用与错误类型的对象时
ValueError 正确的类型对象,但是对象使用不合适的值
ZeroDivisionError 除法,第二参数为0

捕捉异常

基本形式:

try:
    需要执行的操作
except 异常类 as e:
    如果发生异常,执行以下代码
else:
    如果没有发生异常,执行的命令
finally:
    无论如何,都要执行的代码
  • 注意 except as e 的写法,e 是一个变量,记录了异常的类,可以用 print 函数打印出来
  • except 后面的异常类,建议写 Exception,这样就一定能捕获到异常。
  • 捕获到异常,就不会去执行 else 模块

示例:

try:
    name = input('Please input your name: ')
    print('Hello %s' %name)
    print(10/0)
except Exception as e:
    print('Got an error ', e)
else:
    print('OK')
finally:
    print('Game over')
Please input your name: zhong
Hello zhong
Got an error  division by zero
Game over

再举个例子:

import urllib.request

def main():
	try:
		response = urllib.request.urlopen("http://210.35.16.108")
		# response = urllib.request.urlopen("https://www.baidu.com")
	except Exception as e:
		# raise
		print(e)
	else:
		print('无异常则执行,有异常就不执行')
	finally:
		print('不管怎样,最后总会执行这行代码')

if __name__ == '__main__':
	main()

结果:

<urlopen error [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。>
不管怎样,最后总会执行这行代码
[Finished in 21.5s]

捕获多个异常

方法一:

try:
    需要执行的操作
except 异常类1 as e:
    如果发生异常类1,执行以下代码
except 异常类2 as f:
    如果发生异常类2,执行以下代码
else:
    如果没有发生异常,执行的命令
finally:
    无论如何,都要执行的代码
  • except 后面的异常类,如果无需指定,直接写 Exception 即可。
  • 如果需要明确指定异常的类,而且是多个类的情况下,可以使用多个 except 语句。

方法二:

try:
    需要执行的操作
except (异常类1,异常2,异常3) as e:
    如果发生异常,执行以下代码
else:
    如果没有发生异常,执行的命令
finally:
    无论如何,都要执行的代码

抛出异常

raise 关键字可以自主抛出异常,规则如下:

raise NameError([str])

  • raise 后面跟异常的类,类括号里面,可以指定要抛出的异常示例,约详细越好
>>> raise NameError()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError

>>> raise NameError('bad name')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: bad name

例如:

# 当你输入的不是整数,它会报错(ValueError),但你输入的是一个整数后,它会输出你输入的整数。
Q = input("请输入一个整数:")
if type(Q) != type(1):
    raise ValueError
else:
    print(Q)
Q = input("请输入一个整数:")
if type(Q) != type(1):
    raise leixingError("类型错误!")
else:
    print(Q)

总结如下

  1. except语句不是必须的,finally语句也不是必须的,但是二者必须要有一个,否则就没有try的意义了。
  2. except语句可以有多个,Python会按except语句的顺序依次匹配你指定的异常,如果异常已经处理就不会再进入后面的except语句。
  3. except语句可以以元组形式同时指定多个异常,参见实例代码。
  4. except语句后面如果不指定异常类型,则默认捕获所有异常,你可以通过logging或者sys模块获取当前异常。
  5. 如果要捕获异常后要重复抛出,请使用raise,后面不要带任何参数或信息。
  6. 不建议捕获并抛出同一个异常,请考虑重构你的代码。
  7. 不建议在不清楚逻辑的情况下捕获所有异常,有可能你隐藏了很严重的问题。
  8. 尽量使用内置的异常处理语句来替换try/except语句,比如with语句,getattr()方法。
原文地址:https://www.cnblogs.com/id88/p/14210878.html