python的异常处理
- 一,语法错误(解析错误)
- 1,解析错误invalid syntax
- 二,内置的异常
- 1,内置异常
- 三,异常的处理
- 1,基本的try except语句
- 2,except语句
- 3,eles语句
- 4,异常参数
- 5,处理调用函数的异常
- 四,抛出异常raise关键字
- 1,强制抛出异常
- 2,处理并抛出异常
- 五,用户自定义异常(异常类)
- 1,以error结尾,继承父类
- 2,代码实现
- 六,finally语句
- 1,try finally
- 2,return在异常中
- 3,算除法demo
- 4,关于finally注意的点
- 5,用finally关闭文件流
- 七,预定义清理操作
- 1,自动关闭流的操作
一,语法错误(解析错误)
1,解析错误invalid syntax
>>> flag = True>>> if flag print(flag)File "<stdin>", line 1if flag print(flag)^SyntaxError: invalid syntax箭头指的地方少了 :号>>> if flag:... print(flag)...True
二,内置的异常
1,内置异常
- 内置异常是python语句运行时发生的异常
- 分子为0,不存在的名称,类型错误
>>> 1/0 # ZeroDivisionErrorTraceback (most recent call last):File "<stdin>", line 1, in <module>ZeroDivisionError: division by zero>>>>>> var + 3 # NameErrorTraceback (most recent call last):File "<stdin>", line 1, in <module>NameError: name 'var' is not defined>>>>>> '2' + 3 # TypeErrorTraceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: can only concatenate str (not "int") to str>>>
三,异常的处理
1,基本的try except语句
- 输入句子,直到是整数结束
def test():while True:try:x = int(input('请输入整数:\n'))print(x)breakexcept ValueError:print('噢哦,输入数字,再来一次...')
-
try的工作原理
• 首先,执行 try 子句 (try 和 except 关键字之间的(多行)语句)。• 如果没有异常发生,则跳过 except 子句 并完成 try 语句的执行。• 如果在执行try 子句时发生了异常,则跳过该子句中剩下的部分。然后,如果异常的类型和 except 关键字后面的异常匹配,则执行 except 子句 ,然后继续执行 try 语句之后的代码。• 如果发生的异常和 except 子句中指定的异常不匹配,则将其传递到外部的 try 语句中;如果没有找到处理程序,则它是一个未处理异常,执行将停止并显示如上所示的消息。
2,except语句
- 见异常抛出就结束程序。except,可以用元组接收异常。
def test1():try:print(1 + '1', 1/0)except (TypeError, ZeroDivisionError):raise
'''
print(1 + '1', 1/0)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
'''
- except后面的异常可以省略,谨慎使用,可能处理不到别的异常
def except_strip():import systry:f = open('TestError.py', 'r') # oserror 打开不了s = f.readline()i = int(s.strip()) # 可能转换不成数字except OSError as err:print('oserror', err)except ValueError as v:print('转换不了', v)except:print('unexcept error', sys.exc_info()[0]) # 其它的不确定错误raisefinally:f.close()
3,eles语句
- 如果异常在try里面不引发,可以把不引发异常的代码写在else句子里面
def else_except():import sysfor arg in sys.argv[0:]:try:f = open(arg, 'r', encoding='UTF-8')except OSError:print('不能打开', arg)else: # 没用错误,正常执行print('下面是读取的本文件: \n', f.read())f.close()
4,异常参数
- 发生异常时,它可能具有关联值,称为异常参数,参数的存在和类型取决于异常类型。 Exception.args() 返回一异常参数的元组
def except_args():try:raise Exception('arg1', 'arg2')except Exception as e:print(type(e))print(e.args) # ('arg1', 'arg2')print(e)x, y = e.args # 解包参数print(x, y)
5,处理调用函数的异常
def division():print(1/0)passdef my_fails():try:division()except ZeroDivisionError as e:print(e)my_fails()
四,抛出异常raise关键字
1,强制抛出异常
>>> raise NameError('I am wrong...')Traceback (most recent call last):File "<stdin>", line 1, in <module>NameError: I am wrong…
- 参数可简写
>>> raise NameErrorTraceback (most recent call last):File "<stdin>", line 1, in <module>NameError>>>
2,处理并抛出异常
>>> try:... raise NameError... except NameError:... print('name wrong')... raise...name wrongTraceback (most recent call last):File "<stdin>", line 2, in <module>NameError>>>
五,用户自定义异常(异常类)
1,以error结尾,继承父类
- 程序可以通过创建新的异常类来命名它们自己的异常。异常通常应该直接或间接地从 Exception 类派生。
2,代码实现
# 异常类
class Error(Exception):# 用于异常的父类passclass InputError(Error):def __init__(self, expression, msg):self.expression = expressionself.msg = msgclass TransitionError(Error):def __init__(self, previous, next, msg):self.previous = previousself.next = nextself.msg = msg
六,finally语句
1,try finally
>>> try:... raise KeyboardInterrupt... finally:... print('hello world')... hello worldTraceback (most recent call last):File "<stdin>", line 2, in <module>KeyboardInterrupt
2,return在异常中
def bool_return():try:return Truefinally:return False print(bool_return())
3,算除法demo
def divide(x, y):try:result = x / yexcept ZeroDivisionError:print('余数不为0')else:print('结果是:', result)finally:print("我会被打印,因为我是必须被执行的。")divide(1, 0)divide('1', '1')
# 没有对应的NameError处理,所以会在finally执行后,引发异常
4,关于finally注意的点
• 如果在执行 try 子句期间发生了异常,该异常可由一个 except 子句进行处理。如果异常没有被某个 except 子句所处理,则该异常会在 finally 子句执行之后被重新引发。
• 异常也可能在 except 或 else 子句执行期间发生。同样地,该异常会在 finally 子句执行之后被重新引发。
• 如果在执行 try 语句时遇到一个 break, continue 或 return 语句,
则 finally 子句将在执行 break, continue 或 return 语句之前被执行。
• 如果 finally 子句中包含一个 return 语句,
则返回值将来自 finally 子句的某个 return 语句的返回值,
而非来自 try 子句的 return 语句的返回值。
5,用finally关闭文件流
try:f = open('file_name', 'r', encoding='utf-8')f.read()
except:print('unexcept wrong...')raise
finally:if "f" in locals(): # 局部变量作用域的集合print(f)f.close()
- 可以关闭数据库连接,网络流
七,预定义清理操作
1,自动关闭流的操作
>>> f = open('TestError.py', 'r', encoding = 'utf-8') >>> f.read(1)''>>> 上面的代码并没用关流,但是我可能读取文件出错了,f文件流一直开着。用with就可以了,遇到问题时,f也会关闭>>> with opne('1.txt', 'r') as f:... f.read()... Traceback (most recent call last):File "<stdin>", line 1, in <module>NameError: name 'opne' is not defined>>> fTraceback (most recent call last):File "<stdin>", line 1, in <module>NameError: name 'f' is not defined