文章目录
异常和错误
异常
except
try/except/else/finally
try/except
-
最常见的形式
while True:
try:
x = int(input("请输入一个数字(-1表示退出): "))
if x == -1:
break
except ValueError:
print("输入的不是数字,请再次尝试输入!")
# 结果
请输入一个数字(-1表示退出): 2
请输入一个数字(-1表示退出): ?
输入的不是数字,请再次尝试输入!
请输入一个数字(-1表示退出): -1
-
一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行
-
一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组
except (RuntimeError, TypeError, NameError): pass
-
最后一个except子句可以忽略异常的名称,它将被当作通配符使用,捕获未被捕获的异常
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])
-
except
中的写法-
except
后面也不写except: pass
-
except 异常名称或错误名称
except ValueError: pass
-
except 异常名称或错误名称 as 别名
except ValueError as e: pass
-
try/except…else
try/except
语句还有一个可选的else
子句,如果使用这个子句,那么必须放在所有的except
子句之后else
子句将在try
子句没有发生任何异常的时候执行
while True:
try:
x = int(input("请输入一个数字(-1表示退出): "))
if x == -1:
break
except ValueError:
print("输入的不是数字,请再次尝试输入!")
else:
print("进入了无异常的else处理部分....")
# 结果
请输入一个数字(-1表示退出): a
输入的不是数字,请再次尝试输入!
请输入一个数字(-1表示退出): 1
进入了无异常的else处理部分....
请输入一个数字(-1表示退出): -1
try/except/else/finally
- 异常处理的完整形式
finally
无论有没有出现异常,都会执行- 如果一个异常在
try
子句里(或者在except
和else
子句里)被抛出,而又没有任何的except
把它截住,那么这个异常会在 finally 子句执行后被抛出。
while True:
try:
x = int(input("请输入一个数字(-1表示退出): "))
if x == -1:
break
except ValueError:
print("输入的不是数字,请再次尝试输入!")
else:
print("进入了无异常的else处理部分....")
finally:
print("进入了finally处理部分...")
# 结果
请输入一个数字(-1表示退出): a
输入的不是数字,请再次尝试输入!
进入了finally处理部分...
请输入一个数字(-1表示退出): 1
进入了无异常的else处理部分....
进入了finally处理部分...
请输入一个数字(-1表示退出): -1
进入了finally处理部分...
- 注意:当输入
-1
时,try
中需要执行了break
结束循环,但是并没有直接执行,而是先去执行了finally
后执行了break
raise
- 用于抛出一个指定的异常
-
格式
-
raise 异常类
try: raise Exception except: print('捕获到一个异常') # 结果 捕获到一个异常
-
raisse 异常类的实例对象
try: raise Exception('这是一个异常') except Exception as e: print('捕获到一个异常') print('异常信息为:%s' % e) # 结果 捕获到一个异常 异常信息为:这是一个异常
-
assert
assert
(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常
-
格式:
-
assert expression
,不带参数参数-
等价于
if not expression: raise AssertionError
x = 1 assert x == 1 #表达式为True,程序正常继续执行 print('正常') # 结果 正常
x = 1 assert x == 2 #表达式为False时,触发AssertionError print('正常') # 结果 Traceback (most recent call last): File "G:/testSele.py", line 2, in <module> assert x == 2 AssertionError
-
-
assert expression [, arguments]`,带有参数
-
等价于
if not expression: raise AssertionError(arguments)
-
x = 1 assert x == 2, '断言的表达式为False' print('正常') # 结果 Traceback (most recent call last): File "G:/testSele.py", line 2, in <module> assert x == 2, '该表达式为False' AssertionError: 该表达式为False
-
自定义异常
- 过创建一个新的异常类来拥有自己的异常
- 异常类继承自 Exception 类,可以直接继承,或者间接继承
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return self.value
try:
raise MyError('自定义的异常类')
except MyError as e:
print('这个异常是:%s' % e)
# 结果
这个异常是:自定义的异常类
- 当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类
# 基础异常类
class BaseError(Exception):
pass
# 继承自基础异常类的异常类1
class InputError(BaseError):
def __init__(self, expression, message):
self.expression = expression
self.message = message
# 继承自基础异常类的异常类2
class TransitionError(BaseError):
def __init__(self, previous, message):
self.previous = previous
self.message = message
try:
raise InputError('这里是表达式参数','这里是异常或错误的信息')
except InputError as e:
print(e)
# 结果
('这里是表达式参数', '这里是异常或错误的信息')
异常抛出未处理,再抛出
- 如果只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出
try:
raise NameError('名称异常')
except NameError:
print('捕获到异常')
raise
# 结果
Traceback (most recent call last):
File "G:/testSele.py", line 2, in <module>
捕获到异常
raise NameError('名称异常')
NameError: 名称异常
错误
- Error