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("还在正常运行呢。")
    悟已往之不谏,知来者之可追
  • 相关阅读:
    Go源码文件与命令
    K8s控制器
    odoo 在form视图sheet右上角增加按钮
    odoo 常用widget
    odoo tree视图中实现横向滚动条
    可能是智障的高二生活
    千题计划
    闲谈
    线性代数与simplex
    好题集锦
  • 原文地址:https://www.cnblogs.com/ljh-study/p/13896856.html
Copyright © 2011-2022 走看看