zoukankan      html  css  js  c++  java
  • Python3基础(九) 错误和异常

    本文主要介绍Python中的错误和异常,涉及到简单的异常处理、抛出异常以及清理动作。至于自定义异常类,将在介绍类与继承的时候讲到。

    一、定义

    常见的两种错误:语法错误异常

    1、语法错误(Syntax Errors)

    语法错误,也就是解析时错误。当我们写出不符合python语法的代码时,在解析时会报SyntaxError,并且会显示出错的那一行,并用小箭头指明最早探测到错误的位置。比如:

    x = input('please input an integer:')
    if int(x) > 5:
        print 'hello world'
    在python 3中会报语法错误:

    File "/home/songlee/test", line 3
      print 'hello world'
                        ^
    SyntaxError: invalid syntax

    2、异常(Exceptions)

    即使语句或表达式在语法上是正确的,但在尝试运行时也可能发生错误,运行时错误就叫做 异常(Exceptions) 。异常并不是致命的问题,因为我们可以在程序中对异常进行处理。

    >>> 10 * (1/0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ZeroDivisionError: division by zero
    
    >>> 2 + x*3
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'x' is not defined
    
    >>> '2' + 2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: Can't convert 'int' object to str implicitly

    上面展示了三种exception的类型:ZeroDivisionError、NameError、TypeError ,它们都是内置异常的名称。标准异常的名字是内建的标识符 (但并不是关键字)。


    二、处理异常(try…except…)

    我们可以使用 try…except… 语句来处理异常。try 语句块中是要执行的语句,except 语句块中是异常处理语句。一个 try 语句可以有多条的 except 语句,用以指定不同的异常,但至多只有一个会被执行:

    try:
        x = int(input('please input an integer:'))
        if 30/x > 5:
            print('Hello World!')
    except ValueError:
        print('That was no valid number. Try again...')
    except ZeroDivisionError:
        print('The divisor can not be zero, Try again...')
    except:
        print('Handling other exceptions...')

    上面这段代码,当输入a(非数字)时,将抛出ValueError异常;当输入0时,将抛出ZeroDivisionError异常;当抛出其他类型的异常时,将执行except:后的处理语句。

    如果在 try 语句执行时,出现了一个异常,该语句的剩下部分将被跳过。并且如果该异常的类型匹配到了 except 后面的异常名,那么该 except 后的语句将被执行。注意,如果 except 后面没有跟异常名,表示它匹配任何类型的异常,except:必须放在最后。

    一个 except 语句可以同时包括多个异常名,但需要用括号括起来,比如:

    except (RuntimeError, TypeError, NameError):
        pass
    try...except...语句可以有一个可选的 else 语句。else 语句必须要放在所有 except 语句后面,当没有异常发生的时候,else 从句将被执行:

    try:
        name = input('please input an integer:')
        f = open(name, 'r')
    except IOError:
        print('Cannot open', name)
    except:
        print('Unexpected errors.')
    else:
        print('close the file', name)
        f.close()

    三、抛出异常(raise)

    raise 语句允许程序员强制地抛出一个特定的异常,例如:

    >>> raise NameError('HiThere')     # 抛出异常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: HiThere

    raise 抛出的异常必须是一个异常实例或类(派生自 Exception 的类)。


    四、清理动作(finally)

    try 语句有另一种可选的finally从句,用于自定义一些扫尾清理的工作。

    try:
        x = int(input('please input an integer:'))
        if x > 5:
            print('Hello World!')
    except ValueError:
        print('It was not a number. Try again.')
    finally:
        print('Some clean-up actions!')
    与 else 从句的区别在于: else 语句只在没有异常发生的情况下执行,而 finally 语句则不管异常发生与否都会执行。准确的说,finally 语句总是在退出 try 语句前被执行,无论是正常退出、异常退出,还是通过break、continue、return退出。

    >>> def divide(x, y):
    ...     try:
    ...             result = x / y
    ...     except ZeroDivisionError:
    ...             print('error: division by zero!')
    ...     else:
    ...             print('executing else-clause,', 'result is', result)
    ...     finally:
    ...             print('executing finally-clause')
    ... 
    
    >>> divide(2, 1)      # 正常退出
    executing else-clause, result is 2.0
    executing finally-clause
    
    >>> divide(2, 0)      # 异常退出
    error: division by zero!
    executing finally-clause
    
    >>> divide('2', '1')  # 异常退出,异常未被处理。
    executing finally-clause
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in divide
    TypeError: unsupported operand type(s) for /: 'str' and 'str'

    从上面看出,finally 语句在任何情况下都被执行了。对于没有被 except 处理的异常,将在执行完 finally 后被重新抛出。

    另外,有些对象预定义了标准的清理动作(clean-up actions)。当对象不再需要时,该动作将被执行,无论对其使用的操作是否成功。例如下面的文件I/O例子:

    for line in open("myfile.txt"):
        print(line, end="")
    这段代码的问题在于,在此代码成功执行后,文件依然被打开着。但with语句可以让文件对象在使用后被正常的清理掉:
    with open("myfile.txt") as f:
        for line in f:
            print(line, end="")

    在执行该语句后,文件 f 就会被关闭,就算是在读取时碰到了问题,文件 f 也会被关闭。像文件这样的对象,总会提供预定义的清理工作。






    个人站点:http://songlee24.github.com





  • 相关阅读:
    vue报错 error: data.push is not a function
    vue elment.style样式修改(第三方组件自生成元素)
    按元素标签查询多个
    按css查询多个元素
    按CSS查询一个元素
    查询单个元素
    JavaScript 查找元素
    Spring 商品分类
    Spring 使用日志
    Spring 使用日期类型
  • 原文地址:https://www.cnblogs.com/songlee/p/5738114.html
Copyright © 2011-2022 走看看