Python 有两种错误很容易辨认:语法错误和异常(本文将重点介绍python的异常)。
python语法错误:
Python 的语法错误或者称之为解析错,是初学者经常碰到的;
>>>while True print('Hello world') File "<stdin>", line 1, in ? while True print('Hello world') ^ SyntaxError: invalid syntax
函数 print() 被检查到有错误,是它前面缺少了一个冒号 : 。语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。
python异常:
即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行;一般情况下,在Python无法正常处理程序时就会发生一个异常;异常是Python对象,表示一个错误;当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
>>>10 * (1/0) # 0 不能作为除数,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in ? ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定义,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能与 str 相加,触发异常 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: Can't convert 'int' object to str implicitly
异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。
python异常的处理:
python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。异常处理和断言(Assertions)。
异常处理涉及的5个关键字:
try:理解它是扫描器,将可能出现异常的代码放入其中;如果在执行的过程中出现异常对象了,扫描器会立即察觉到此异常对象,但是它没有处理它的能力,所以会将异常对象给到except(捕获器)进行处理。
except:理解它是捕获器,后面可以定义异常类型,并且和as关键字配合使用;定义多个except是合法的,但是它的执行顺序是有由上往下,一旦匹配上某个except,之后的就不执行了;匹配成功就理解将异常对象捕获住并且kill,顺便会执行except内部的代码。(注意:except不能捕获处理类似于语法错误这种情况)
finally:将一定需要被执行的代码定义其中,【记住】:finally一定会被执行(核心);使用场景:像关闭文件、断开数据库连接等行为都可以放入到finally中。
else:位置在finally前,except后;效果/作用类似于循环;没有异常对象出现,else就会被执行,反之不会被执行。
raise:手动抛出一个异常类型的对象,定义:raise 异常类型(msg)。
定义格式:
格式一: 多个except语句并列存在,每个except包含一种类型,如果它们之间没有子父类的关系(互斥),那么谁上谁下无所谓, 如果它们之间存在子父类的关系(包含),那么小的在上,大的在下。
try: 语句块1 except 异常类型1 as e: 语句块2 except 异常类型2 as e: 语句块3 except 异常类型3 as e: 语句块4 finally: 语句块5
格式二:一个except具备多个捕获能力(捕获多种不同类型异常对象)。
try: 语句块1 except 异常类型1 as e: 语句块2 except 异常类型2 as e: 语句块3 except 异常类型3 as e: 语句块4 except (异常类型4,异常类型5,...,异常类型m) as e: finally: 语句块5
格式三:Exception是所有异常类型的父类型,它都是定义在最后一个except的位置。
try: 语句块1 except 异常类型1 as e: 语句块2 except 异常类型2 as e: 语句块3 except 异常类型3 as e: 语句块4 except (异常类型4,异常类型5,...,异常类型m) as e: 语句块5 except Exception as e: 语句块6 finally: 语句块7
格式四: 【Exception的简化版使用】:如果定义了except,那么它必须是最后一个except,它可以理解为是Exception的简化形式
try: 语句块1 except 异常类型1 as e: 语句块2 except 异常类型2 as e: 语句块3 except 异常类型3 as e: 语句块4 except (异常类型4,异常类型5,...,异常类型m) as e: 语句块5 except: 语句块6 finally: 语句块7
代码演示自动抛出异常对象:
2 3 def div(a,b): 4 print(a / b) 5 6 div(10,0) 7 8 # 演示异常处理的方式一:try ... except ... 9 try: 10 print(10/0) 11 except ZeroDivisionError as e: 12 print(e) 13 14 try: 15 print("abc"+123) 16 except TypeError as e: 17 print(e) 18 19 try: 20 print(a) 21 except NameError as e: 22 print(e) 23 24 try: 25 lt = [1,2,3,4,5] 26 print(lt[5]) 27 except IndexError as e: 28 print(e) 29 30 try: 31 fr = open(r'C:UsersAdministratorDesktopkaifanglist1.txt','r',encoding='utf-8') 32 print(fr.read()) 33 fr.close() 34 except FileNotFoundError as e: 35 print(e) 36 37 except(ZeroDivisionError,TypeError,NameError,IndexError,FileNotFoundError) as e: 38 print('我能捕获5种类型的异常对象...') 39 40 except Exception as e: 41 print('我是所有异常类型的父类型,我能解决所有的异常类型对象...') 42 43 except: 44 print('我是Exception的简化形式,我只能出现在最后一个except的位置...')
代码演示finally语句的使用:将一定要被执行的代码定义在finally中,不管之前的代码怎么样(异常是否被解决),finally一定会被执行,在后期的学习和开发中,我们将关闭文件、关闭数据库连接等操作都定finally中。
1 try: 2 fr = open(r'C:UsersAdministratorDesktopa.txt','r') # 文件能打开 3 print(fr.read()) 4 print(10 / 0) 5 # fr.close() # 因为关闭文件操作是一定要被执行的 但是在try里面也有可能存在风险性,当print(10 / 0)行不了,则无法执行close操作,所以关闭文件需要放在finally语句当中
6 except: 7 print('解决异常') 8 finally: 9 print('我是finally,我一定会被执行...') 10 fr.close() 11 12 13 # 但是如果一开始就是一个打不开的文件,则也没有办法关闭文件 14 fr = 0 15 try: 16 fr = open(r'C:UsersAdministratorDesktopa111.txt','r') # 没有此文件名 (文件存在则fr不为None值) 17 print(fr.read()) 18 except: 19 print('解决异常') 20 finally: 21 print('我是finally,我一定会被执行...') 22 if fr: # fr为None值则if为False,否则为True,执行以下指令(为了安全性) 23 fr.close()
finally案例演示二(进一步理解):
1 # Finally案例:分别输出了哪些内容,返回值是多少 2 3 def func(): 4 try: 5 print('我是try...') 6 print(10 / 2) 7 return 1 #执行此步 则函数就结束了,又因为finally一定要被执行,所以return 1不会被执行,直接调到finally 8 except: 9 print('我是except...') 10 return 2 11 finally: 12 print('我是finally...') 13 return 3 14 15 num = func() 16 print(num) 17 '''结果得到是 18 我是try... 19 5.0 20 我是finally... 21 3''' 22 23 # 如果题目改为如下,则 24 def func(): 25 try: 26 print('我是try...') 27 print(10 / 0) 28 return 1 29 except: 30 print('我是except...') 31 return 2 #执行此步 则函数就结束了,又因为finally一定要被执行,所以return 2不会被执行,直接调到finally 32 finally: 33 print('我是finally...') 34 return 3 35 36 num = func() 37 print(num) 38 '''结果得到是 39 我是try... 40 我是except... 41 我是finally... 42 3''' 43
【补充】with open...操作:不需要程序员人为的去书写 close() 函数
1 With open(r'C:UsersAdministratorDesktopa.txt','r')as fr: 2 print(fr.read())
解决异常也是一样:
1 try: 2 with open(r'C:UsersAdministratorDesktopa.txt','r') as fr: 3 print(fr.read()) 4 except: 5 print('解决异常...')
代码演示else语句和异常处理机制配合使用:如果try中没有出现异常对象,那么else语句就一定会被执行,如果try中出现了异常对象,就算被处理了,else还是不会被执行。
1 try: 2 print('我是try...') 3 print(10 / 0) 4 except Exception as e: 5 print('我是except...') 6 else: 7 print('我是else...') 8 finally: 9 print('我是finally...')
10 #得到 11 我是try... 12 我是except... 13 我是finally... 14 15 #如果把print(10 / 0) 改为print(10 / 2) 16 17 #得到 18 我是try... 19 5.0 20 我是else... 21 我是finally...
代码演示raise的使用:(手动抛出异常对象)
1 age = 18 2 if age < 0 or age > 130: 3 try: 4 raise Exception('年龄有问题...') 5 except: 6 print('年龄不合法...正在处理') 7 pass 8 else: 9 print('年龄为:%d' %age) 10 print('能走吗?') 11 12 #得到结果为 13 年龄为:18 14 能走吗? 15 16 #如果第一行是age=-18 17 #得到结果为 18 年龄不合法...正在处理 19 能走吗?
1 # 演示异常处理的方式二:不断往上级传递异常对象,回避问题的方式 2 3 def m1(): 4 print('我是m1...') 5 print(10 / 0) 6 7 def m2(): 8 print('我是m2...') 9 # try: 10 m1() 11 # except: 12 # pass 13 14 def m3(): 15 print('我是m3...') 16 try: 17 m2() 18 except: 19 pass 20 21 m3() 22 #得到结果 23 我是m3... 24 我是m2... 25 我是m1...
python标准异常总结:
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
【注意事项】:
1).try...finally这种格式是合法的,但是它丧失了解决异常对象的能力(所以不会使用)
2).else语句必须配合except使用,出现位置一定是在最后一个except的后面
3).常见的运行时异常类型:ZeroDivisionError:分母为0的异常;TypeError:类型有误的异常; NameError:没有定义就使用的异常;IndexError:下标越界的异;FileNotFoundError:文件找不到的异常;...
4).with open ... as ...语句可以优化原始的open操作!体现:它不需要手动close()文件对象
总结:学习异常对象简单归纳为5个关键字:try except finally else raise
python的assert(断言):
Python的assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。
语法格式如下:assert expression
等价于:
if not expression:
raise AssertionError
assert 后面也可以紧跟参数: assert expression [, arguments]
等价于:
if not expression:
raise AssertionError(arguments)
代码演示assert示例:
1 >>> assert True # 条件为 true 正常执行 2 >>> assert False # 条件为 false 触发异常 3 Traceback (most recent call last): 4 File "<stdin>", line 1, in <module> 5 AssertionError 6 7 >>> assert 1==1 # 条件为 true 正常执行 8 >>> assert 1==2 # 条件为 false 触发异常 9 Traceback (most recent call last): 10 File "<stdin>", line 1, in <module> 11 AssertionError 12 13 >>> assert 1==2, '1 不等于 2' 14 Traceback (most recent call last): 15 File "<stdin>", line 1, in <module> 16 AssertionError: 1 不等于 2 17 18 19 # 判断当前系统是否为 Linux,如果不满足条件则直接触发异常,不必执行接下来的代码: 20 import sys 21 assert ('linux' in sys.platform), "该代码只能在 Linux 下执行" 22 # 接下来要执行的代码