Python学习笔记(十三)——编译错误和异常处理

异常和异常类

Python常见错误

语法错误

源代码存在拼写语法错 误,这些错误导致Python 编译器无法把Python源代 码转换为字节码,故也称 之为编译错误。
>>> print("我爱山大"}
SyntaxError: invalid syntax

运行时错误

• 程序中没有导入相关的模块:NameError
程序中包括零除运算
打开不存在的文件:
FileNotFoundError
>>> 1/0
ZeroDivisionError: division by zero

逻辑错误

程序可以执行(程序运 行本身不报错),但执行 结果不正确。Python解释 器对此无能为力,需要根据结果来调试判断。
>>> from math import sqrt
>>> a=1;b=2;c=3
>>> x1=-b+sqrt(b**2-4*a*c)/2*a
math domain error

异常处理

简单地说,异常是指程序运行时引发的错误,引发错误的原因有很多,例如除零、 下标越界、文件不存在、网络异常、类型错误、名字错误、字典键错误、 磁盘空 间不足,等等。
代码运行时如果发生了异常,将生成代表该异常的一个对象,并交由 Python 解释器寻找相应的代码来处理这一异常。合理地使用异常处理结果可以使得程序更加健壮,具有更强的容错性,不会因为用户不小心的错误输入或其他运行时原因而造成程序终止。

异常类

所有异常都是基类 BaseException 的派生类,它们都定义在 BaseExceptions 块中。
如果这个异常对象没有进行处理和捕捉,程序就会用所谓的回溯( traceback ,一 种错误信息)终止执行, 这些信息包括错误的名称(例如 NameError )、原因和 错误发生的行号。

异常类的层次结构 

(1)NameError。尝试访问一个未申明的变量。
>>> noname #报错。NameError: name 'noname' is not defined
(2)SyntaxError。语法错误。
>>> int a #报错。SyntaxError: invalid syntax
(3)AttributeError。访问未知对象属性。
>>> a=1
>>> a.show() #报错。AttributeError: 'int' object has no attribute 'show'
(4)TypeError。类型错误。
>>> 11 + 'abc' #报错。TypeError: unsupported operand type(s) for +: 'int' and 'str'
(5)ValueError。数值错误。
>>> int('abc') #报错。ValueError: invalid literal for int() with base 10: 'abc’ (6)ZeroDivisionError。零除错误。
>>> 1/0 #报错。ZeroDivisionError: division by zero
(7)IndexError。索引超出范围。
>>> a=[10,11,12]
>>> a[3] #报错。IndexError: list index out of range
(8)KeyError。字典关键字不存在。
>>> m = {'1':'yes', '2':'no'}
>>> m['3'] #报错。KeyError: '3'

常见的异常类

异常名称
描述
ZeroDivisionError
( 或取模 ) ( 所有数据类型 )
NameError
未声明 / 初始化对象 ( 没有属性 )
SyntaxError
解释器发现语法错误
IndexError
序列中不存在的索引
KeyError
使用映射中不存在的键
FileNotFoundError
试图打开不存在的文件
AttributeError
尝试访问未知对象属性
IndentationError
缩进错误
TabError
Tab 和空格混用
ImportError
导入模块 / 对象失败
IOError
输入 / 输出操作失败
AssertionError
断言语句失败

 抛出异常类

大部分由程序错误而产生的错误和异常,一般由 Python 虚拟机自动抛出。
如果判断某种错误情况,则可以创建相应的异常类的对象,并通过 raise 语句抛出
Python 虚拟机出现错误时会自动抛出异常
>>> 1/0
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module> 1/0
ZeroDivisionError: division by zero
使用 raise 语句主动抛出异常 .
>>> if a<0:raise ValueError("数值不能为负数")

#Traceback (most recent call last):
#File "<pyshell#6>", line 1, in <module>
#if a<0:raise ValueError("数值不能为负数")
#ValueError: 数值不能为负数

主动抛出异常类

raise 语句主动抛出一个异常,异常 / 错误对象必须有一个名字,且它们是 Error Exception 类的子类。
raise [exceptionName [(reason)]]
exceptionName 指定异常的名字,是 Error Exception 类的子类。
reason 对异常的描述。

#实例
>>> if a<0: raise ValueError("数值不能为负数")

使用类名引发异常

raise 语句指定异常的类名时, 会创建该类的实例对象,然后引发异常。

 raise IndexError

Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
raise IndexError
IndexError

 通过显示地创建异常类的对象, 直接使用对象来引发异常。

index = IndexError()
raise index
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
raise index
IndexError

指定异常的描述信息

当使用 raise 语句抛出异常时,可以给异常类指定描述信息。
raise IndexError("索引下标超出范围")
Traceback (most recent call last):
File "D:/异常.py", line 1, in <module>
raise IndexError("索引下标超出范围")
IndexError: 索引下标超出范围

 异常处理

Python 语言采用结构化的异常处理机制。
通过 try 语句来定义代码块,以运行可能抛出异常的代码;
通过 except 语句,可以捕获特定的异常并执行相应的处理;
通过 finally 语句,即保证处理异常,也可在事后清理资源等。
tip: 在try中出现错误代码(报错),不需要管,他会根据报错类型,执行对应的except中的代码块。
finally语句则会用来做收尾工作(可有可无)

常用的异常处理

  • 简单异常: try语句+except异常名
  • 多个异常: try语句+多个excep异常名
  • 所有异常:try语句 +except
  • 没有异常: try语句+ except+ else
  • 终止行为: try语句+except+finally语句

捕获所有异常情况的方法

当程序中出现大量异常时,捕获这些异常是非常麻烦的。这时,我们可以在 except 子句中不指明异常的类型,这样,不管发生何种类型的异常,都会 执行 except 里面的处理代码。(可以少列很多限制条件)
try:
    num1 = input('请输入第1个数:')
    num2 = input('请输入第2个数:')
    print(int(num1)/int(num2))
# 放在所有except语句最后
except Exception as result:
    print('捕获到异常:%s'%result)

未捕获异常 

如果 try 语句没有捕获到任何的错误信息,就不再执行任何 except 语句,而 是会执行 else 语句。
try:
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print(int(num1)/int(num2))
except Exception as result:
    print("捕捉到异常:%s"%result)
else:
    print("程序正常运行,没有捕捉到异常")

 中止行为

在程序中,无论是否捕捉到异常, 都必须要执行某件事情,例如关 闭文件、释放锁等,这时可以提 finally 语句处理。通常情况下, finally 用于释放资源
tip:是否异常均执行。
import time
try:
    f = open('test.txt',"w+")
    while True:
        content = f.read()
        if len(content) == 0:
          break
    time.sleep(2)
    print(content)
finally:
    f.close()
    print('关闭文件')

try-except语句小结

自定义异常

应用场景

前面捕捉的异常都是系统内置的,在某些错误时自动触发。然而程序员有时需要根据自己的需求设定异常。例如,用户注册账户是需要限定用户名、密码等信息的类型和字数。

创建用户自定义异常需要完成如下的工作

创建一个继承Exception类的子类,就是自定义异常类。

当遇到自己设定的错误时,使用raise语句抛出自定义的异常。

实例

class ShortInputException(Exception):
    def __init__(self, length, atleast):
        Exception.__init__(self)
        self.length = length
        self.atleast = atleast
try:
    s = input('请输入 --> ')
    if len(s) < 3:
        raise ShortInputException(len(s), 3)
except EOFError:
    print ('你输入了一个结束标记EOF')
except ShortInputException as x:
    print ('ShortInputException: 长度是 %d, 至少应是 %d' % (x.length, x.atleast))
else:
    print ('没有异常发生.')

 Python官方讲解exception类

断言处理

在程序调试阶段往往需要判断代码执行过程中变量的值或类型等关键信息。 断言相比 print 语句更加灵活和高效,其一般应用于下列情况。
前置条件断言:代码执行之前必须具备的特性
后置条件断言:代码执行之后必须具备的特性
前后不变断言:代码执行前后不能变化的特性
断言的主要功能是帮助程序员调试程序,以保证程序运行的正确性;断言一般 在开发调试阶段使用。即调试模式时断言有效,优化模式运行时,自动忽略 断言。

assert语句

assert 语句又称作断言,指的是 期望用户满足指定的条件
当用户定义的约束条件不满足时,会出发 AssertionError 异常,所以 assert 句可以当做条件式的 raise 语句。
assert 布尔表达式 ,<描述性字符>
                        ||
                        V
if not 布尔表达式:
        raise AssertionError(<描述性字符串>)
assert 后面紧跟一个布尔表达式,相当于条件。描述性字符串是当条件为 false 时作
为异常的描述信息。
>>> a = 0
>>> assert a!=0,"a的值不能为0"
Traceback (most recent call last):
File "D:/异常.py", line 2, in <module> assert a!=0,"a的值不能为0"
AssertionError: a的值不能为0

实例

 

 程序基本调试方法

在程序实际运行之前,查找和修正其错误的过程称为调试 (debugging)

语法错误的调试

对于编辑错误, Python 解释器会直接剖出异常,用户可以根据异常信息修改 程序的代码。
>>> if 1>2
SyntaxError: invalid syntax
>>> x
NameError: name 'x' is not defined

运行时错误的调试

对于运行时错误, Python 解释器也会抛出异常,在代码中可以通过 try…except 语 句捕获并处理。如果程序中没有 try…except ,则 Python 解释 器直接打印出异常信息。
>>> f=open("123.txt")
FileNotFoundError: [Errno 2] No such file or directory: '123.txt'
>>> 123+"abc"
TypeError: unsupported operand type(s) for +: 'int' and 'str'

逻辑错误处理的常用方法

包括断点跟踪、输出信息等方法
有的集成开发环境( IDE )可以设置断点,并查看变量等
通过 print 语句输出程序运行过程中变量值(跟踪信息),是观察和调试程序运行逻辑正确性的有效方法

 单条语句调试

函数调试 

 

传送门:Python全套学习笔记

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛哥带你学代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值