zoukankan      html  css  js  c++  java
  • 0705 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("		剪刀石头布终极对战")
        print()
        print("		1、输入石头(1)/剪刀(2)/布(3)")
        print("		2、输入0退出程序
    ")
        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("
    请输入0~3之间的数字:
    石头(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("第{}局:	{}".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("
    游戏退出,欢迎再来!")
            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("用户胜负情况:
    {}胜、{}负、{}平
    胜算率为:{:.1f}%".format(*last_result))
        # 将用户胜负情况写入文件
        game_info = "{}胜、{}负、{}平、{:.1f}%胜算
    ".format(*last_result)
        # file_handle(result_file, game_info)
        write_file(result_file, game_info)
    
    
    if __name__ == '__main__':
        main()

    *******请大家尊重原创,如要转载,请注明出处:转载自:https://www.cnblogs.com/shouhu/,谢谢!!******* 

  • 相关阅读:
    array_map()与array_shift()搭配使用 PK array_column()函数
    Educational Codeforces Round 8 D. Magic Numbers
    hdu 1171 Big Event in HDU
    hdu 2844 poj 1742 Coins
    hdu 3591 The trouble of Xiaoqian
    hdu 2079 选课时间
    hdu 2191 珍惜现在,感恩生活 多重背包入门题
    hdu 5429 Geometric Progression 高精度浮点数(java版本)
    【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
    hdu::1002 A + B Problem II
  • 原文地址:https://www.cnblogs.com/shouhu/p/12666199.html
Copyright © 2011-2022 走看看