8 - Python 异常处理
1、什么是异常?为什么要捕获异常?
- 程序在运行时,提示的一些错误信息,这就是异常
- 即 Python 的程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
- 如果程序执行抛出异常,,则程序会中断执行,大多数的异常都不会被程序处理,所以需要捕获异常,并对异常进行处理
2、异常基类
在处理异常的时候,我们会接触到很多错误基类,比较常用的罗列如下:
BaseException:所有异常的基类
Exception:常规错误的基类
ZeroDivisionError:除(或取模)零(所有数据类型)
AssertionError:断言语句失败
AttributeError:对象没有这个属性
ImportError:导入模块/对象失败
LookupError:无效数据查询的基类
IndexError:序列中没有此索引(index)
KeyError:映射中没有这个键
NameError:未声明/初始化对象(没有属性)
SyntaxError:Python 语法错误
IndentationError:缩进错误
TypeError:对类型无效的操作
ValueError:传入无效的参数
UnicodeError:Unicode 相关的错误
UnicodeDecodeError:Unicode 解码时的错误
UnicodeEncodeError:Uncode编码时错误
UnicodeTranslateError:Unicode转换时错误
Warning:警告的基类
SyntaxWarning:可疑的语法的警告
3.异常的完整语法格式
- try(译:踹)、except(译:亦可赛泼特)、else(译:艾欧斯)、finally(译:发呢李)
try: 尝试执行的代码 pass except 错误类型1: 针对错误类型1,对应的代码处理 pass except 错误类型2: 针对错误类型2,对应的代码处理 pass except (错误类型3, 错误类型4): 针对错误类型3 和 4,对应的代码处理 pass except Exception as result: # 能接收(捕获)所有的异常 # 会将接收到的异常赋值给result变量 打印错误信息 print(result) else: 没有异常才会执行的代码 pass finally: 无论是否有异常,都会执行的代码 print("无论是否有异常,都会执行的代码")
4.在异常中,try关键字下的块语句、except下的块语句、else下的块语句、finally下的块语句执行逻辑
1.如果 try 下的块语句没有异常,
- else 下的块语句和 finally 下的块语句都会被执行,
- except下的块语句不会被执行
2.如果 try 下的块语句有异常,
- 会在当前语句抛出异常,抛出异常的行下面的语句不会被执行,
- except 语句会从上到下开始判断,如果 except 能捕获到异常,那么其他 except 不会再判断,else也不会被执行,
- 但finally仍然会被执行
def handle_except(): try: # 只要出现冒号, 那么会告诉Python冒号后面的是一个块语句(往往要缩进4个空格) # 在try语句下面, 写一些有可能会出错的代码 # 在try块语句中, 如果没有抛出异常(没有报错), 那么会将try块语句全部执行完, # 且不会执行except块语句 # 如果出现异常, 那么在try块语句中, 出现异常的地方,剩下的程序不会被执行 num = int(input("请输入一个数字: ")) # 抛出了一个异常 print(1 / num) print(a_deng) # Exception print("num下面的语句") return "菲菲真靓!" # except ValueError: # 只能捕获指定的 ValueError异常 # print("值错误的异常!") # print("这里会使用日志器来记录日志!") # 只要有一个except语句被执行, 那么其他的except不再会被执行 except (ValueError, ZeroDivisionError): # 使用一个except同时处理多个异常 print("除数为零的异常或者值错误的异常!") print("这里也会使用日志器来记录日志!") except Exception as err: # 会将接收到的异常对象赋值给err变量 # 能接收(捕获)所有的异常 print(f"err为: {err}") # 可以打印err变量 print("能捕获所有的异常") else: # 不能加语句 print("try语句没有抛出异常的情况下, 会被执行! 正常执行!") finally: # 不能加语句 print("不管是否有异常, finally一定会被执行! ") print("继续往下执行!") print(handle_except())
示例:判断用户输入的是否是浮点类型
while True: try: one_num = float(input("请输入一个数字: ")) break except Exception as e: pass print(f"one_num值为{one_num}, 类型为{type(one_num)}") 执行结果: 请输入一个数字: . 请输入一个数字: . 请输入一个数字: 1 one_num值为1.0, 类型为<class 'float'>
4.编写如下程序,优化去生鲜超市买橘子程序
- a.收银员输入橘子的价格,单位:元/斤
- b.收银员输入用户购买橘子的重量,单位:斤
- c.计算并且 输出 付款金额
- d.使用捕获异常的方式,来处理用户输入无效数据的情况
def is_int_or_digit(num): """ 判断用户输入的数字是否为正数 :param num:数字 :return:True or False """ try: one_num = float(num) return True if one_num >= 0 else False except ValueError: return False def main(): while True: # 1. 输入橘子单价 orange_price = input("请输入橘子价格:") if not is_int_or_digit(orange_price): print("输入的橘子价格为{},输入有误!".format(orange_price)) continue break while True: # 2. 输入橘子重量 orange_weight = input("请输入橘子重量:") if not is_int_or_digit(orange_weight): print("输入的橘子重量为{},输入有误!".format(orange_weight)) continue break # 3. 计算金额 # 将橘子单价转换成浮点数 orange_price_flt = float(orange_price) # 将橘子重量转换成浮点数 orange_weight_flt = float(orange_weight) # 计算付款金额 money = orange_price_flt * orange_weight_flt print("橘子每斤{:.1f}元,您购买了{:.1f}斤,需要支付{:.1f} 元!".format(orange_price_flt, orange_weight_flt, money)) if __name__ == '__main__': main()
5.编写如下程序,剪刀石头布程序
- a.提示用户输入要出的拳 —— 石头(1)/剪刀(2)/布(3)
- b.电脑随机出拳
- c.比较胜负,显示用户胜、负还是平局
- d.使用捕获异常的方式,来处理用户输入无效数据的情况
- e.多次进行游戏,可以让用户选择退出游戏,退出后需要显示胜利情况,例如:用户5局胜、3局败、2局平
- f.当程序结束之后,要求下一次运行程序能够获取用户历史胜负情况
- h.如果使用文件保存用户历史胜负数据,需要使用异常来处理文件不存在的情况(选做)
import random import os def menu_info(): """ 菜单显示信息 :return: """ print() print("=" * 50) print("\t\t剪刀石头布终极对战") print() print("\t\t1、输入石头(1)/剪刀(2)/布(3)") print("\t\t2、输入0退出程序\n") print("=" * 50) def check_input(num): """ 判断用户输入的是否为0到3之内的正整数 :param num: 数字 :return: True or False """ try: one_num = int(num) return True if one_num in range(4) else False except ValueError: return False def user_vs_computer(user_player, computer_player): """ 判断用户输赢 :param user_player: 用户猜拳数字 :param computer_player: 电脑猜拳数字 :return: """ # 用户胜的情况: # 用户出石头(1),电脑出剪刀(2) # 用户出剪刀(2),电脑出布(3) # 用户出布(3),电脑出石头(1) user_win_tup = ((1, 2), (2, 3), (3, 1)) if (user_player, computer_player) in user_win_tup: print("欧耶!电脑弱爆了!!!") return "胜" elif computer_player == user_player: print("心有灵犀,要不咋再来一盘!") return "和" else: print("不行,我要和你决战到天亮!") return "败" def user_input(): """ 校验用户输入 :return: 正整数 """ while True: user_num = input("\n请输入0~3之间的数字:\n石头(1)/剪刀(2)/布(3)/退出(0) ") if not check_input(user_num): print("输入错误,请重新输入!") else: break return int(user_num) def read_file(file_path, mode='r', encoding='utf-8'): """ 从文件中读取数据 :param file_path: 文件路径 :param mode: 文件打开模式 :param encoding: 文件编码 :return: 如果文件不存在或者内容为空, 则返回None, 否则返回每一行内容列表 """ # 判断文件是否存在 if not os.path.exists(file_path) or not os.path.isfile(file_path): print("文件不存在或者路径有误!") return None # 打开文件 one_file = open(file_path, mode=mode, encoding=encoding) # 读取文件内容 datas_list = one_file.readlines() # 关闭文件 one_file.close() return datas_list if datas_list else None def write_file(file_path, data, mode='a', encoding='utf-8'): """ 写数据到文件 :param file_path: 文件路径 :param data: 添加的数据 :param mode: 文件打开模式 :param encoding: 文件编码 :return: """ # 打开文件 one_file = open(file_path, mode=mode, encoding=encoding) # 添加内容到文件 one_file.write(data) # 关闭文件 one_file.close() def main(): result_file = "game_result.txt" win_count = 0 # 胜利次数 fail_count = 0 # 失败次数 peace_count = 0 # 平局次数 game_count = 0 # 游戏总次数 win_rate = 0 # 胜算率为0 # 1、显示游戏历史胜负情况 print("游戏历史胜负情况如下:") handle_result = read_file(result_file) if not handle_result: print("游戏记录为空") elif isinstance(handle_result, list): # 如果返回的是读取的数据列表 for key, value in enumerate(read_file(result_file),start=1): print("第{}局:\t{}".format(key, value[:-1])) # 1、显示游戏界面 menu_info() # 2、开始游戏 while True: computer_num = random.randint(1, 3) user_num = user_input() if user_num == 0: print("\n游戏退出,欢迎再来!") break # 判断胜负 result = user_vs_computer(user_num, computer_num) game_count += 1 if result == '胜': win_count += 1 elif result == '败': fail_count += 1 else: peace_count += 1 # 游戏结束,显示胜利情况 try: win_rate = (win_count / game_count) * 100 except ZeroDivisionError: print("出现除0异常!") last_result = (win_count, fail_count, peace_count, win_rate) print("用户胜负情况:\n{}胜、{}负、{}平\n胜算率为:{:.1f}%".format(*last_result)) # 将用户胜负情况写入文件 game_info = "{}胜、{}负、{}平、{:.1f}%胜算\n".format(*last_result) # file_handle(result_file, game_info) write_file(result_file, game_info) if __name__ == '__main__': main()
*******请大家尊重原创,如要转载,请注明出处:转载自:https://www.cnblogs.com/shouhu/,谢谢!!*******
本文仅供参考;如果这篇文件对你有所帮助,麻烦动动发财的小手,推荐一波支持下万分感谢
*******请大家尊重原创,如要转载,请注明出处:作者:守护@往昔;转载自:https://www.cnblogs.com/shouhu/,谢谢!!*******