zoukankan      html  css  js  c++  java
  • Python基础25 异常堆栈跟踪,释放资源,自定义异常和主动抛出

    主动抛出和自定义异常还有点问题,之后抽空完成

      1 #异常处理
      2 
      3 #try-except嵌套
      4 #try和except也是可以嵌套的
      5 #和if-else不同的是
      6 #try-except的嵌套是判定异常的,如果内部出现异常
      7 #就会优先判定内部的except,如果没有找到合适的
      8 #就会跳出,到外面的except中来寻找
      9 
     10 import datetime as dt
     11 
     12 def read_date_form_file(filename):
     13     try:
     14         file=open(filename)
     15         try:
     16             in_date=file.read()
     17             in_date=in_date.strip()
     18             date=dt.datetime.strptime(in_date,"%Y-%m-%d")
     19             return date
     20         except ValueError as e:
     21             print("内层处理ValueError异常")
     22             print(e)
     23     except FileNotFoundError as e:
     24         #没有找到文件
     25         print("外层处理FileNotFoundError异常")
     26         print(e)
     27     except OSError as e:
     28         #输入输出异常
     29         print("外层处理OSError异常")
     30         print(e)
     31 
     32 #这里我们就完成了对try-except的嵌套
     33 #直观的来看,程序显然变得复杂了
     34 #所以一般情况下,我们尽可能的不去使用这种嵌套的形式
     35 
     36 date_1=read_date_form_file('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source.txt')
     37 print(date_1)
     38 #这样便可以正常输出了
     39 #我们再来查看一下except的异常抛出
     40 date_1=read_date_form_file('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source_2.txt')
     41 print(date_1)       #date_source_2.txt文件内容为20BB-10-25
     42 #内层处理ValueError异常,抛出成功
     43 date_1=read_date_form_file('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/fake.txt')
     44 print(date_1)
     45 #外层处理FileNotFoundError异常
     46 #[Errno 2] No such file or directory: 'C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/fake.txt'
     47 #这里显然关于文件存不存在的问题,内部的except是没有解决办法的
     48 #所以这里自然的寻找到了外层的except中来
     49 
     50 print("///////////////////////")
     51 
     52 #多重异常捕获
     53 #简单点来将,就是在except()括号中写多个异常的名字
     54 #就会自动去判定异常了
     55 #这里不做赘述
     56 '''
     57     except (FileNotFoundError,ValueError) as e:
     58 
     59         print(e)
     60         #类似于此的方法
     61 '''
     62 
     63 print("///////////////////////////")
     64 
     65 #异常堆栈跟踪
     66 #我们可以通过Python中的内置模块traceback的print_exc()函数来实现
     67 #它可以打印堆栈跟踪信息
     68 #基本格式如下:
     69 #traceback.print_exc(limit=None,file=None,chain=True)
     70 #                  limit表示限制堆栈跟踪的个数,None表示不限制个数
     71 #                           file表示是否输出堆栈跟踪的信息到文件里去,默认None表示不输入信息进文件
     72 #                                   chain为True表示将__cause__和__context__等属性连接起来,就像解释器本身打印一样
     73 
     74 import datetime as dt
     75 import traceback as tb
     76 
     77 def read_date_from_file_2(filename):
     78     try:
     79         file=open(filename)
     80         in_date=file.read()
     81         in_date=in_date.strip()
     82         date=dt.datetime.strptime(in_date,"%Y-%m-%d")
     83         return date
     84     except (ValueError,OSError) as e:
     85         print("请调用method_1方法解决")
     86         tb.print_exc()
     87 
     88 date_2=read_date_from_file_2('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/fakething.txt')
     89 print("日期={0}".format(date_2))
     90 #我们这里调用的是fakething就是不存在的文件
     91 #然后返还了堆栈数据:
     92 #Traceback (most recent call last):
     93  # File "C:Usersadminsource
    eposRush_BRush_Byichangyichang_2.py", line 79, in read_date_from_file_2
     94   #  file=open(filename)
     95 #FileNotFoundError: [Errno 2] No such file or directory: 'C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/fakething.txt'
     96 #就可以更加准确的看到错误的地方
     97 
     98 print("///////////////////////////")
     99 
    100 #finally和else在之前的一章有讲过
    101 #但是不够仔细
    102 #这里再仔细讲一遍
    103 
    104 #释放资源
    105 #有时候try-except会占用很多资源
    106 #所以这里我们用finally或者as with来释放资源
    107 
    108 #try-except-finally代码块
    109 #try和except运行完后用finally来释放资源
    110 
    111 def read_date_form_file_3(filename):
    112     try:
    113         file=open(filename)
    114         in_date=file.read()
    115         in_date=in_date.strip()
    116         date=dt.datetime.strptime(in_date,"%Y-%m-%d")
    117         return date
    118     except(ValueError,OSError):
    119         print("出现异常")
    120     finally:
    121         file.close()
    122 
    123 date_3=read_date_form_file_3('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source.txt')
    124 print("日期={0}".format(date_3))
    125 #这里我就成功运行了
    126 #这里通过finally的file.close()完成了对文件的关闭
    127 #从而达到了释放资源的目的
    128 #我们再进行一次尝试
    129 #date_3=read_date_form_file_3('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/fake.txt')
    130 #print("日期={0}".format(date_3))
    131 #但是这次却报错了,为什么?
    132 #原因其实很简单,我们导入的filename是假的,系统是找不到这个文件的
    133 #所以这里我们会抛出异常,但是最后运行的finally代码块是 file.close()
    134 #由于文件根本不存在,没有打开过文件,所以这里的file.close()自然无法关闭
    135 #就会报错
    136 
    137 #接下来我们可以通过else来完善这个代码块
    138 
    139 
    140 def read_date_form_file_4(filename):
    141     try:
    142         file=open(filename)
    143     except OSError:         
    144         print("文件未打开")
    145     else:                           #通过else成功分成了两种情况
    146         print("文件成功打开了")
    147         try:
    148             in_date=file.read()
    149             in_date=in_date.strip()
    150             date=dt.datetime.strptime(in_date,"%Y-%m-%d")
    151             return date
    152         except(ValueError,OSError):
    153             print("出现异常")
    154         finally:                    #也就将finally代码块放置在了文件以及打开了区域
    155             file.close()
    156 
    157 date_4=read_date_form_file_4('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source.txt')
    158 print("日期={0}".format(date_4))
    159 
    160 #即使存在文件未打开,也不会影响运行
    161 date_4=read_date_form_file_4('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/fake.txt')
    162 print("日期={0}".format(date_4))
    163 
    164 print("///////////////////")
    165 
    166 #with as 代码块自动管理资源
    167 #with as 模块可以自动的释放资源,在as后面声明一个资源变量
    168 #在with as代码块执行完毕后会自动的释放资源
    169 
    170 def read_date_from_file_5(filename):
    171     try:
    172         with open(filename) as file:    #这里是定义了一个资源文件file然后执行了open
    173             #这里就是with as定义的代码块
    174             in_date=file.read()
    175             #在执行完读取file里的数据以后
    176             #立刻执行上面as
    177             #立刻释放file的资源
    178         in_date=in_date.strip()
    179         date=dt.datetime.strptime(in_date,"%Y-%m-%d")
    180         return date
    181     except(ValueError,OSError):
    182         print("出现异常")
    183     
    184 date_5=read_date_from_file_5('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source.txt')
    185 print("日期={0}".format(date_5))
    186 
    187 print ("////////////////////////////")
    188 
    189 #自定义异常类
    190 #一般来讲会开发自己的Python的库的时候
    191 #基本上都会自己来定义一些异常类
    192 #实现定义异常类需要继承Exception类或其子类
    193 
    194 class MyException(Exception):   #定义一个异常类,并将Exception作为父类
    195     def __init__(self,message):     #这里message是异常描述信息
    196         super().__init__(message)   #这里是调用父类Exception的代码
    197         #这样这个我们定义的自定义类就包括了系统的所有异常
    198 #接下来
    199 #我们再根据需要来定义新的异常类型,但是这时候父类就要写我们的自定义异常类
    200 
    201 class GeshiError(MyException):
    202     
    203     def __init__(self,a,b):         #定义两个数据待会方便收录
    204         self.a=a
    205         self.b=b
    206         #但是这个例子中暂时不需要这个
    207     
    208 
    209     def __str__(self):              #然后这里重新定义一下str然后再输出数据
    210         return "日期的格式出错了"
    211 #这样建立的目的是为了后面方便通过raise来显示化抛出异常
    212 
    213 
    214 
    215 
    216 print("////////////////////////")
    217 
    218 #显示抛出异常
    219 #我们之前接触的异常都是由系统生成的
    220 #当异常抛出的时候,系统会创建一个异常对象然后抛出
    221 #单也可以通过raise语句显示抛出异常
    222 #格式:
    223 #raise BaseException 或其子类实例
    224 #简单来讲就是 raise 后面添加基础异常的名字,或者我们自己定义的异常
    225 
    226 def read_date_from_file_6(filename):
    227     try:
    228         c=1
    229         file=open(filename)            
    230         in_date=file.read()
    231         in_date=in_date.strip()
    232         date=dt.datetime.strptime(in_date,"%Y-%m-%d")
    233         if c==1 :
    234             raise MyException("C==1")
    235         return date
    236     except ValueError as e:
    237         raise MyException('1') 
    238     except OSError as e:
    239         raise MyException("2") 
    240     except FileNotFoundError as e:
    241         raise MyException("3") 
    242     except MyException as e:
    243         print(e)
    244 
    245     
    246 date_6=read_date_from_file_6('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source.txt')
    247 print("日期={0}".format(date_6))
    248 #输出一个错误的格式
    249 date_7=read_date_from_file_6('C:/Users/admin/source/repos/Rush_B/Rush_B/yichang/date_source_2.txt')
    250 print("日期={0}".format(date_7))
    251 
    252 #和try-except不同的是 raise手动抛出异常以后,就不会继续运行了
    253 print("还在正常运行呢。")
    悟已往之不谏,知来者之可追
  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/ljh-study/p/13896856.html
Copyright © 2011-2022 走看看