主动抛出和自定义异常还有点问题,之后抽空完成
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("还在正常运行呢。")