python学习之---异常处理

异常处理

异常 Exception

错误 Error

逻辑错误,算法写错,
笔误: 变量名写错,
函数或类使用错误
错误可以避免

**异常Exception **

例如:open 函数,文件不存在,或者创建文件时,文件已经存在,或者访问一个网络文件,突然断网,是个意外情况
异常是不可避免的

错误和异常

在高级语言中,一般都有错误和异常,异常可以捕获,并被处理,但是错误是不能被捕获的

产生异常

  • raise 语句显式的抛出异常
  • Python解释器自己检测到异常并引发它
def bar():
    print('~~')
    raise Exception('my Exception')  # 主动引出异常
    print('~~~~')
bar()

异常的捕获

try:
    待捕获异常的代码块
except:
    异常的处理代码块

举例:

print('before')                 
try :                             
    print(1/0)
except:
    print('error')
print('after')
>>>
before
error
after
###也可以指定异常的类型
print('before')
try :
    print(1/0)
except ArithmeticError:# 捕获算术异常
except KeyError:  #捕获keyerror异常
    print('error')
print('after')

总结: 异常捕获时,except 后面加的错误类型要与上面产生的异常相匹配.不然起不到捕获异常的作用.

上例执行到c=1/0时产生异常抛出,由于使用了try --except 语句块捕捉到了这个异常,异常生成位置之后语句不在执行,转而执行对应的except部分的语句,最后执行try–except语句块之外的语句

异常类及继承层次

BaseException      #基类
 +-- SystemExit        #解析器请求退出
 +-- KeyboardInterrupt #用户中断执行
 +-- GeneratorExit     #生成器发生异常
 +-- Exception         #常规错误的基类        
      +-- StopIteration   #迭代器值超出
      +-- StandardError   #所以的内建标准异常的基类
      |    +-- BufferError	#缓冲错误
      |    +-- ArithmeticError#算术错误
      |    |    +-- FloatingPointError #浮点数计算错误
      |    |    +-- OverflowError# 数值运算超出最大限制
      |    |    +-- ZeroDivisionError#除(或取模)错误
      |    +-- AssertionError#断言语句失败
      |    +-- AttributeError#对象没有这个属性
      |    +-- EnvironmentError#操作系统错误基类
      |    |    +-- IOError#输入输出操作失败
      |    |    +-- OSError#操作系统错误
      |    |         +-- WindowsError (Windows)#系统调用失败
      |    |         +-- VMSError (VMS)#虚拟机调用失败
      |    +-- EOFError#没有内建输入,到大EOF标记(end of file)
      |    +-- ImportError#导入模块错误
      |    +-- LookupError#无效数据查询的基类
      |    |    +-- IndexError#索引错误
      |    |    +-- KeyError#关键字key错误
      |    +-- MemoryError #内存溢出错误
      |    +-- NameError#未声明/初始化对象(属性)
      |    |    +-- UnboundLocalError#访问未初始化的本地变量
      |    +-- ReferenceError#弱引用
      |    +-- RuntimeError#一般的运行时错误
      |    |    +-- NotImplementedError#尚未实现的方法
      |    +-- SyntaxError#Python语法错误
      |    |    +-- IndentationError#缩进错误
      |    |         +-- TabError#Tab和空格错误
      |    +-- SystemError#一般的解释器系统错误
      |    +-- TypeError#对类型无效的错误
      |    +-- ValueError#传入无效的参数
      |         +-- UnicodeError#Unicode相关错误
      |              +-- UnicodeDecodeError#编码错误
      |              +-- UnicodeEncodeError#解码错误
      |              +-- UnicodeTranslateError#转化错误
      +-- Warning# 警告的基类
           +-- DeprecationWarning#关于被弃用的特征的警告
           +-- PendingDeprecationWarning#关于特征将会被废弃的警告
           +-- RuntimeWarning#可疑的运行行为
           +-- SyntaxWarning#可疑语法警告
           +-- UserWarning# 用户代码生成的警告
           +-- FutureWarning#关于构造将来语义会有改变的警告
	   +-- ImportWarning#导入错误
	   +-- UnicodeWarning#编码错误
	   +-- BytesWarning#bytes警告

举例详解:

# 捕获这个异常
import sys
try:
    sys.exit(100)  #状态返回码 是自己设定状态码
except SystemExit: # 换成Exception能否捕获  (# 不能,)
    print('SysExit')
print('outer') # 是否执行?
>>>  
SysExit
outer

Exception 及子类

Exception是所有内建的、非系统退出的异常的基类,自定义异常类应该继承自它

SyntaxError 语法错误

Python将这种错误也归到异常类下面的Exception下的子类,但是这种错误是不可捕获的

自定义异常类

从Expection 继承的类

class MyException(Exception): # 自定义的异常类从Exception 继承
	pass
try:
	raise MyException()  # 实例化
except MyException: # 捕获自定义异常
print('catch the exception')	

多种捕获

except可疑捕获多个异常

class MyException (Exception):
    pass

def foo():
    try :
        a =1/0
        raise NotImplementedError
        raise MyException()
    except ArithmeticError:
        print('Arhth')
    except Exception:  #多种异常,只要捕获一种则不再继续执行
        print('oa')
    except :  # 相当于except  all 
        print('all')
    print('leave here')
# 越具体的异常越往上写,
# 捕获是从到下依次比较,如果匹配,则执行匹配的except语句块/                                                                                                                    

捕获原则:

  • 捕获是从下往下比较,如果匹配,则执行匹配的except语句块
  • 如果被一个except 语句捕获,其他except语句就不会再次捕获了
  • 如果没有任何一个except 语句捕获到这个异常,则该异常向外抛出

捕获的原则

从小到大,从具体到宽泛

as子句

首先看个例子:

class A :pass 
try :
#     1/0
#     raise 1
#     raise 'abc'
#     raise {}
#     raise A
#     raise A()
except :
    print('catch the except')
#上面的都能打印出catch the except 

被抛出的异常,应该是异常类的实例,如何获得这个对象呢?使用as子句

class MyException(Exception):
    def __init__(self, code, message):
        self.code = code
        self.message = message
try:
    raise MyException  
except MyException as e:
    print('catch my exception')
except Exception as e :
    print('{}'.format(e))
# 运行结果如下, 为什么?
>>> __init__() missing 2 required positional arguments: 'code' and 'message'

raise 后面跟类型是无参构造实例,因此需要两个参数,但并未给,所以会报错

raise语句

raise后要求应该是BaseException类的子类或实例,如果是类,将被无参实例化。
raise后什么都没有,表示抛出最近一个被激活的异常,如果没有被激活的异常,则抛类型异常。这种方式很少用

finally 子句

finally
最终,即最后一定要执行的,try…finally语句块中,不管是否发生了异常,都要执行finally的部分

try:
    f = open('test.txt')  # 尝试打开
except Exception as e:  #文件不存在报错
    print('{}'.format(e)) # 打印错误类型
finally:  #最终要执行 
    print('清理工作')
    try:
        f.close()
    except Exception as e:
        print(e)

异常的传递

def fo1():
    return 1/0
def fo2():
    print('fo2 start')
    fo1()
    print('fo2 stop')
fo2()

foo2调用了foo1,foo1产生的异常,传递到了foo2中。
异常总是向外层抛出,如果外层没有处理这个异常,就会继续向外抛出
如果内层捕获并处理了异常,外部就不能捕获到了
如果到了最外层还是没有被处理,就会中断异常所在的线程的执行。注意整个程序结束的状态返回值。

异常的捕获时机

1,立即捕获 需要立即返回一个明确的结果

2,边界捕获

封装产生了边界
例如:写了一个模块,用户调用这个模块的时间捕获异常,模块内部不需要捕获,处理异常,一旦内部处理了外部调用者就无法感知异常.

例如open函数,出现异常时交给调用者,文件存在,就不用再创建,看是否修改还是删除,
例如自己写了一个类,使用open函数,出现异常不知道如何处理继续向外层抛出,一般来书最外层也是边界,必须处理这个异常,否则线程会退出

else子句

try:
	ret = 1 * 0
except ArithmeticError as e:
	print(e)
else:
	print('OK')
finally:
	print('fin')

else子句.没有任何异常发生时则执行

总结

try:
    <语句>#运行别的代码
except <异常类> as <变量名>:
    <语句> #捕获某种类型的异常并获得对象
else:
    <语句>#如果没有异常发生
finally:
    <语句> #退出try时总会执行
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值