Python 异常

Python 异常

工作过程

while true:
	try:
		x = int(input("Please enter a number:"))
		break
	except ValueError:
		print('非法数字')

try 语句的工作原理如下:

  • 首先执行 try 子句;
  • 如果没有异常发生,则跳过 except 子句并完成 try 语句的执行;
  • 如果在执行 try 语句时发生了异常,则跳过该子句剩下的部分,然后进行下面的异常匹配;
  • 找到匹配后,程序进入对应的 except 子句中执行语句,否则执行停止。

一个 try 语句可能有多个 except 子句,以指定不同异常的处理程序,但是except 子句最多只会执行一个。一个 except 子句可以将多个异常命名为带括号的元组,如:

except(RuntimeError,TypeError,ZeroDivisionError):
	pass

继承规则

class B(Exception):
	pass
	
class C(B):
	pass
	
class D(C):
	pass

for cls in [B, C, D]:
	try:
		raise cls()
	except D:
		print('D')
	except C:
		print('C')
	except B:
		print('B')

except 子句中的类和发生的异常是同一种或者是发生的异常的基类时,此 except 子句可以捕捉到异常;相反当 except 子句中的类是异常的子类时,此 except 子句无法捕捉到异常。上面例子输出B、C、D。修改 except 子句类的顺序为B、C、D,则新的例子输出为 B、B、B。因为 BC、D 的基类,可以捕捉到 C、D 的异常,因此,B、C、D 引起的异常都进入到 except B 子句中。
所以说,当 try 语句引起的异常可能存在继承关系时,一定要注意 except 子句的顺序,子类 except 语句尽量放在前面,基类 except 语句尽量放在后面。
最后的 except 子句可以省略掉异常名,以用作通配符。但请谨慎使用,因为以这种方式很容易掩盖真正的变成错误!它还可用于打印错误消息,然后重新引发异常。
try except 语句有一个可选的 else 语句,在使用时必须放在所有的 except 子句后面。对于在 try 子句中不引发异常时必须执行的代码来说很有用。如:

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()

使用 else 子句比向 try 子句添加额外的代码要好,因为它避免了意外捕获由try......except 语句保护的代码未引发的异常,即可能是else 子句引发的异常,使用 else 子句这样的写法更加的清楚。

抛出异常

raise NameError('HiThere')

raise 唯一的参数就是要抛出的异常,这个参数必须是一个异常实例或者异常类。如果是异常类,它将通过调用没有参数的构造函数来隐式实例化。
如果不对异常进行处理,则可以使用更简单的 raise 语句重新引发异常。

try:
	raise NameError('HiThere')
except NameError:
	print('An exception flew by!')
	raise
try:
    raise
except NameError:
    print(123)

这种情况下,raise 会引发 RuntimeError

用户自定义的异常

用户创建的异常必须直接或者间接地继承基类异常BaseException

finally 子句

try:
	<>
except Error:
	<>
else:
	<>
finally:
	<>

finally 子句将作为 try 语句结束前的最后一项任务被执行。finally 子句不论 try 语句是否产生了异常都会被执行。
以下是 finally 会遇到的几种情况:

  • 执行 try 子句引发异常:

该异常可被 except 子句处理,如果没有被处理,则在 finally 语句重新被引发。

  • exceptelse 子句中出现异常:

该异常会在 finally 子句之后被重新引发。

如果 finally 子句中包含一个 return 语句,则返回值将来自 finally 子句的 return 返回值,而非来自 try 子句的 return 返回值。
例如:

>>>def bool_return():
...    try:
...		   return True
...	   finally:
...		   return False
>>>bool_return()
False

一个更加复杂的例子:

def int_return(x, y):
	try:
		result = x/y
	except ZeroDivisionError:
		return 1
	else:
		return 2
	finally:
		return 3
>>>int_return(2, 1)
3
>>>int_return(2, 0)
3

在实际应用程序中,finally 对释放外部资源(如文件或者网络连接)非常有用,无论是否成功使用资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值