异常类型

  1. 语法错误

    1. print "hello world"
    2. >>SyntaxError: Missing parentheses in call to 'print'
  2. 运行错误 | 类型 | 含义 | 实例 | | —- | —- | —- | | AssertionError | 当 assert 关键字后的条件为假时,程序运行会停止并抛出 AssertionError 异常 | | | AttributeError | 当试图访问的对象属性不存在时抛出的异常 | | | IndexError | 索引超出序列范围会引发此异常 | | | KeyError | 字典中查找一个不存在的关键字时引发此异常 | | | NameError | 尝试访问一个未声明的变量时,引发此异常 | | | TypeError | 不同类型数据之间的无效操作 | | | ZeroDivisionError | 除法运算中除数为 0 引发此异常 | |

异常处理

try…except语句块

  1. 首先执行 try 中的代码块,如果执行过程中出现异常,系统会自动生成一个异常类型,并将该异常提交给 Python 解释器,此过程称为捕获异常。
  2. 当 Python 解释器收到异常对象时,会寻找能处理该异常对象的 except 块,如果找到合适的 except 块,则把该异常对象交给该 except 块处理,这个过程被称为处理异常。如果 Python 解释器找不到处理异常的 except 块,则程序运行终止,Python 解释器也将退出。
    1. try:
    2. a = int(input('输入被除数'))
    3. b = int(input('输入除数'))
    4. c = a/b
    5. print('您输入的俩个数相除的结果是:',c)
    6. except(ValueError,ArithmeticError):
    7. print('程序发生了数字格式异常、算术异常之一')
    8. except:
    9. print('未知异常')
    10. print('程序继续运行')

    获取特定异常的有关信息

    每种异常类型都提供了如下几个属性和方法,通过调用它们,就可以获取当前处理异常类型的相关信息:
  • args:返回异常的错误编号和描述字符串;
  • str(e):返回异常信息,但不包括异常信息的类型,这个和直接输出e结果一样;
  • repr(e):返回较全的异常信息,包括异常信息的类型。 ```python try: 1/0 except Exception as e:

    访问异常的错误编号和详细信息

    print(e.args) print(str(e)) print(repr(e))

    (‘division by zero’,) division by zero ZeroDivisionError(‘division by zero’)

  1. <a name="thGfO"></a>
  2. ### try...except...else...finally
  3. 正常执行的程序在try下面执行,在执行中如果发生了异常,则中断当前执行然后执行except中的部分,如果没有异常即不执行except的情况下,则会执行else中的语句,finally语句是最后无论是否有异常都要执行的代码。如果没有except,不能写else和finally。
  4. ```python
  5. try:
  6. result = 20 / int(input('请输入除数:'))
  7. print(result)
  8. except ValueError:
  9. print('必须输入整数')
  10. except ArithmeticError:
  11. print('算术错误,除数不能为 0')
  12. else:
  13. print('没有出现异常')
  14. finally:
  15. print('执行完成')
  16. print("继续执行")
  17. >>请输入除数: 3
  18. >>6.666666666666667
  19. >>没有出现异常
  20. >>继续执行

raise用法

基本语法

raise [exceptionName[(reason)]]
其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息.

基本用法

  1. raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
  2. raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
  3. raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。 ```python raise

    > RuntimeError Traceback (most recent call last) in ——> 1 raise

RuntimeError: No active exception to reraise raise ZeroDivisionError

> ZeroDivisionError Traceback (most recent call last)

in ——> 1 raise ZeroDivisionError

ZeroDivisionError: raise ZeroDivisionError(‘除数不能为零’)

> ZeroDivisionError Traceback (most recent call last)

in ——> 1 raise ZeroDivisionError(“除数不能为零”)

ZeroDivisionError: 除数不能为零

  1. ```python
  2. try:
  3. a = input("输入一个数:")
  4. #判断用户输入的是否为数字
  5. if(not a.isdigit()):
  6. raise ValueError("a 必须是数字")
  7. except ValueError as e:
  8. print("引发异常:",repr(e))
  9. >>s
  10. >>引发异常: ValueError('a 必须是数字')
  1. try:
  2. a = input("输入一个数:")
  3. if(not a.isdigit()):
  4. raise ValueError("a 必须是数字")
  5. except ValueError as e:
  6. print("引发异常:",repr(e))
  7. raise
  8. >>>
  9. 输入一个数: ds
  10. 引发异常: ValueError('a 必须是数字')
  11. ---------------------------------------------------------------------------
  12. ValueError Traceback (most recent call last)
  13. <ipython-input-41-8ee213d8d387> in <module>
  14. 2 a = input("输入一个数:")
  15. 3 if(not a.isdigit()):
  16. ----> 4 raise ValueError("a 必须是数字")
  17. 5 except ValueError as e:
  18. 6 print("引发异常:",repr(e))
  19. ValueError: a 必须是数字

当在没有引发过异常的程序使用无参的 raise 语句时,它默认引发的是 RuntimeError 异常。例如:

  1. try:
  2. a = input("输入一个数:")
  3. if(not a.isdigit()):
  4. raise
  5. except RuntimeError as e:
  6. print("引发异常:",repr(e))
  7. >>输入一个数: ds
  8. >>引发异常: RuntimeError('No active exception to reraise')

sys.exc_info()方法:获取异常信息

模块 sys 中,有两个方法可以返回异常的全部信息,分别是 exc_info() 和 last_traceback(),这两个函数有相同的功能和用法,本节仅以 exc_info() 方法为例。

exc_info()方法

exc_info() 方法会将当前的异常信息以元组的形式返回,该元组中包含 3 个元素,分别为 type、value 和 traceback,它们的含义分别是:

  • type:异常类型的名称。
  • value:捕获到的异常实例。
  • traceback:是一个 traceback 对象。

    1. import sys
    2. try:
    3. x = int(input("请输入一个被除数"))
    4. print("30除以",x,"等于",30/x)
    5. except:
    6. print(sys.exc_info())
    7. print("其它异常...")
    8. >>>
    9. 请输入一个被除数: 0
    10. (<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x0000019F451170C0>)
    11. 其他异常...

    第 2 行是抛出异常的全部信息,这是一个元组,有 3 个元素,第一个元素是一个 ZeroDivisionError 类;第 2 个元素是异常类型 ZeroDivisionError 类的一个实例;第 3 个元素为一个 traceback 对象。其中,通过前 2 个元素可以看出抛出的异常类型以及描述信息,对于第 3 个元素,是一个 traceback 对象,无法直接看出有关异常的信息,还需要对其做进一步处理。
    要查看traceback对象包含的内容,需要引进trackback模块
    该模块提供了一个标准接口,用于提取,格式和打印Python程序的堆栈痕迹。 它完全模仿了Python解释器在打印堆栈跟踪时的行为。 当您想在程序控制下打印堆栈迹线时,这非常有用,例如在解释器周围的“包装器”中。

  • traceback.print_tb(tb, limit=None, file=None)

1.tb: 这个就是traceback object, 是我们通过sys.exc_info获取到的
2.limit: 这个是限制stack trace层级的,如果不设或者为None,就会打印所有层级的stack trace
3.file: 这个是设置打印的输出流的,可以为文件,也可以是stdout之类的file-like object。如果不设或为None,则输出到sys.stderr。

  1. import sys
  2. import traceback
  3. try:
  4. x = int(input("请输入一个被除数"))
  5. print("30除以",x,"等于",30/x)
  6. except:
  7. trackbace.print_tb(sys.exc_info()[2])
  8. print("其它异常")
  9. >>>
  10. 请输入一个被除数 0
  11. 其它异常
  12. File "<ipython-input-46-4d6f7e4107ab>", line 5, in <module>
  13. print("30除以",x,"等于",30/x)
  • traceback.print_exception(exc_type,exc_value,traceback_error,limit=None,file=sys.stderr) ```python import sys import traceback

try: x = int(input(‘请输入一个数’)) result = 30/x print(result) except Exception as e: exc_type,exc_value,traceback_error = sys.exc_info() print(traceback.print_exception(exc_type,exc_value,traceback_error,limit=3,file=sys.stderr))

> Traceback (most recent call last): File “.\demo.py”, line 6, in result = 30/x ZeroDivisionError: division by zero None ```

  • traceback.print_exc()为print_exception自动填充sys.exc_info()的三个参数
  • traceback.format_exc(imit=None, chain=True),返回一个字符串 ```python import sys import traceback

try: x = int(input(‘请输入一个数’)) result = 30/x print(result) except Exception as e:

  1. #exc_type,exc_value,traceback_error = sys.exc_info()
  2. print(traceback.format_exc())

```