美文网首页Python
10.断言与异常

10.断言与异常

作者: 小哲1998 | 来源:发表于2020-03-13 21:25 被阅读0次

    一、实验目的

    • 断言
    • NameError
    • TypeError
    • 异常处理(try..except)
    • 异常抛出(raise)
    • finally 子句

    二、知识要点

    1.断言

    Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,语法格式为:

    assert expression
    

    例如我们的代码只能在windows系统下运行,可以先判断当前系统是否符合条件:

    import sys
    assert ('linux' in sys.platform), '错误'
    print("hello")
    

    会输出:

    Traceback (most recent call last):
      File "F:/Python/10/eg 10-1.py", line 5, in <module>
        assert ('linux' in sys.platform), '错误'
    AssertionError: 错误
    
    Process finished with exit code 1
    

    当我们将linux更改为win32就会输出hello

    2.错误和异常

    在程序执行过程中发生的任何错误都是异常。每个异常显示一些相关的错误信息,比如我们在 Python3 中使用 Python2 独有的语法就会发生SyntaxError

    print 'hello'
    

    输出为:

      File "F:/Python/10/eg 10-1.py", line 11
        print 'hello'
              ^
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello')?
    

    而如果我们多打了一个空格:

     print('hello')
    

    就会出现IndentationError

      File "F:/Python/10/eg 10-1.py", line 12
        print('hello')
        ^
    IndentationError: unexpected indent
    
    Process finished with exit code 1
    

    接下来将介绍几种常见的异常:
    2.1 NameError
    当访问一个未定义的变量则会发生 NameError,例如:print(a)会输出:

    Traceback (most recent call last):
      File "F:/Python/10/eg 10-1.py", line 15, in <module>
        print(a)
    NameError: name 'a' is not defined
    

    2.2 ZeroDivisionError
    当把0作为除数则会发生 ZeroDivisionError,例如:print(1/0)会输出:

    Traceback (most recent call last):
      File "F:/Python/10/eg 10-1.py", line 18, in <module>
        print(1/0)
    ZeroDivisionError: division by zero
    

    2.3 TyprError
    当操作或函数应用于不适当类型的对象时引发TyprError,较为常见的是字符串与整数加法,例如:print('1'+1)会输出:

    Traceback (most recent call last):
      File "F:/Python/10/eg 10-1.py", line 21, in <module>
        print('1'+1)
    TypeError: can only concatenate str (not "int") to str
    

    标准异常:https://www.runoob.com/python/python-exceptions.html


    3.异常处理
    异常处理

    我将通过一个例子来解释上图的流程:

    a = 0
    while a != -1:
        try:
            a = int(input("输入一个数字:"))
            if a == -1:
                break
        except ValueError:
            print("输入类型有误")
        else:
            print(1 + a)
            print("输入类型无误")
        finally:
            print("结束")
    print("循环结束")
    

    我们分别输入1a,最后输入-1结束,输出如下:

    输入一个数字:1
    2
    输入类型无误
    结束
    输入一个数字:a
    输入类型有误
    结束
    输入一个数字:-1
    结束
    循环结束
    

    这个过程是这样的:

    • 如果我们输入一个数字-1,程序停止循环,程序等价为:
    while a != -1:
        try:
            a = int(input("输入一个数字:"))
            if a == -1:
                break
        finally:
            print("结束")
    print("循环结束")
    

    注意:finally只要执行了try不管有没有异常都会执行。在真实场景的应用程序中,finally 子句用于释放外部资源(文件或网络连接之类的),无论它们的使用过程中是否出错。


    • 如果我们输入一个字母‘a’,程序异常,程序等价为:
    while a != -1:
        try:
            a = int(input("输入一个数字:"))
            if a == -1:
                break
        except ValueError:
            print("输入类型有误")
        finally:
            print("结束")
    print("循环结束")
    

    即程序在try中的语句中出现了异常,会在except中匹配对应的异常类型,如果未匹配则会终止程序,如果匹配上对应的异常类型会执行对应except下的语句,如果语句中有fially,在执行完except中的语句会执行fianlly中的语句。

    • 如果我们输入一个整数1,程序无异常,程序等价为:
    while a != -1:
        try:
            a = int(input("输入一个数字:"))
            if a == -1:
                break
        else:
            print(1 + a)
            print("输入类型无误")
        finally:
            print("结束")
    print("循环结束")
    

    即程序通过try语句检测之后没有异常,如果是try-except格式,在没有异常的情况下会直接跳出try-except程序块,继续向下执行;如果是try-except-else格式,在没有异常的情况下会进入else语句中的代码;如果是try-except-else-finally格式,在执行完else语句会执行finally语句中的内容。

    4.抛出异常

    使用raise语句主动抛出异常的意思是开发者可以自己制造程序异常,这里的程序异常不是指发生了内存溢出、列表越界访问等系统异常,而是指程序在执行过程中,发生了用户输入的数据与要求数据不符、用户操作错误等问题,这些问题都需要程序进行处理并给出相应的提示。处理这些问题多使用判断语句,在判断语句体内进行相应的问题处理,如果处理问题的语句过多,就会导致代码复杂化,代码结构不够清晰。在这种情况下,可以使用raise语句主动抛出异常,由异常处理语句块进行处理。例如:

    try:
        print("请输入登录账号:")
        username = input(">>:")
        if username != "zhe":
            raise Exception("用户名输入错误")
        print("请输入密码:")
        psw = input(">>:")
        if psw != "123456":
            raise Exception("密码输入错误")
    except Exception as e:
        print(e)
    

    在上述代码中,当我们输入用户名不是zhe时会主动抛出异常用户名输入错误而此时except语句会捕获异常并输出,而如果我们用户名无误,程序会继续向下进行,在密码输入处如果错误会抛出密码输入错误异常,由except捕获之后输出,如果一直无误,程序执行完之后跳出try-except语句。执行下一程序块。

    三、实验内容

    1.玩转函数

    本次挑战中我们将实现一个程序,将分钟转为小时和分钟。在 MinutesToHours.py 文件中实现一个函数 Hours(),将用户输入的 分钟数 转化为 小时数和分钟数,并要求小时数尽量大。将结果以 XX H, XX M 的形式打印出来。


    输入:80

    输出:1 H,20 M

    注意:

    • 代码中不要使用 input() 函数。
    • 如果用户输入的是一个负值,程序需要raise 来抛出ValueError 异常。
    • Hours()函数调用的时候,需要使用 try...except 处理异常。获取异常后,在屏幕上打印出Parameter Error 提示用户输入的值有误。
    • 代码:
    import sys
    
    
    def Hours(minute):
        if minute < 0:
            raise ValueError("负值")
        else:
            print("{} H,{} M".format(int(minute / 60), minute % 60))
    
    
    try:
        Hours(int(sys.argv[1]))
    except ValueError:
        print("Parameter Error")
    
    • 控制台的输出为:
    (venv) F:\Python\10>python hour.py 70
    1 H,10 M
    

    有关sys.argv[]的解释
    sys.argv[value]中对于输入的内容实际上保存为了一个列表,列表的第一个元素即为脚本,例如我们写一个输出脚本print_f.py,脚本中的代码如下:

    import sys
    
    a = sys.argv[0]
    print(a)
    

    我们通过控制台在根目录运行,输入:python print_f,敲击回车,会输出print_f
    此时我们更改一下脚本中的代码为:

    import sys
    
    a = sys.argv[1]
    print(a)
    

    我们再通过控制台在根目录输入:python print_f hello敲击回车会输出hello
    我们再更改一次代码:

    import sys
    
    a = sys.argv[2:]
    print(a)
    

    在控制台中输入:python print_f a b c d e敲击回车输出的为:['b', 'c', 'd', 'e']
    通过上面的例子我们容易理解sys.argv的用法。

    四、实验结果

    相关文章

      网友评论

        本文标题:10.断言与异常

        本文链接:https://www.haomeiwen.com/subject/gwwyshtx.html