Python中的异常

Posted by JustDoDT on January 16, 2018

1. 认识异常

help(TypeError)

class TypeError(Exception)
 |  Inappropriate argument type.
 |  
 |  Method resolution order:
 |      TypeError
 |      Exception
 |      BaseException
 |      object
 |  
 |  Methods defined here:
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from BaseException:
 |  
 |  __delattr__(self, name, /)
:
  • 错误类型其实都是类的实例;TypeError是继承Exception的,把Exception叫做父类或者基类。

1.1 Python的异常结构

https://docs.python.org/3/library/exceptions.html#exception-hierarchy 从官网截图如下:

avatar

在python中的所有异常都是继承自BaseException。BaseException直接分为四大类:

  • SystemExit : Python退出异常
  • KeyboardInterrupt: 键盘打断异常(Ctrl + C)
  • GeneratorExit :生成器退出异常
  • Exception :普通异常(只会使用这部分的异常)

1.2 try … except

用try … except 捕获异常

try:
    f = open('test.py','r')
except:
    print('发生了异常')

执行上面代码的结果为:

发生了异常

例子2:

try:
    x = 0
    y = 1/x
except:
    print('发生了异常')

执行上面代码的结果为:

发生了异常
1.2.2 捕获具体的异常
try:
    f = open('test.py','r')
except FileNotFoundError:
    print('发生了异常')    # 当文件不存在的时候就会打印

执行上面代码的结果为:

发生了异常

try:
    x = 0
    y = 1/x
except FileNotFoundError:
    print('发生了异常')     # 会抛出ZeroDivisionError异常

执行上面代码的结果为:

Traceback (most recent call last):
  File "/home/pyvip/tmp/pycharm_project_90/hahha.py", line 45, in <module>
    y = 1/x
ZeroDivisionError: division by zero    
1.2.3 捕获多种异常

例子1:

执行上面代码的结果为:

请输入正确的文件路径

例子2:

try:
    x = 0
    y = 1/x
except FileNotFoundError:
    print('请输入正确的文件路径')
except ZeroDivisionError:
    print('分母不能为0')
except Exception:
    print('其他的普通异常')

代码的执行结果为:

分母不能为0

1.3 raise

raise是主动抛出异常,就是没有异常的也可以抛出异常。

执行上面代码的结果为:

Traceback (most recent call last):
  File "/home/pyvip/tmp/pycharm_project_90/hahha.py", line 32, in <module>
    raise TypeError('我就想您报错')     # 主动抛出错误
TypeError: 我就想您报错
1.3.2 更加丰富的结构
  • else,finnaly都是可以加到异常处理里面去的
  • else是没有异常的时候会被执行掉
  • finnaly不管有没有异常都会被执行掉

    try: x = 0 except Exception: print(‘发生了普通异常’) # 不打印 else: print(‘没有发生异常’) # 打印 finally: print(‘怎么都会执行’) # 打印

执行上面代码的结果为:

没有发生异常
怎么都会执行

注意:

不是所有的异常都可以捕获到的

如下面这种情况:

try:
    print(‘Hello World')
except SyntaxError as e:
    print(e)

执行上面的代码运行的结果为:

   print(‘Hello World')
               ^
SyntaxError: invalid character in identifier

语法错误,属于Exception里面的,但是却捕获不到。

2. 断言

In [1]: a = 2

In [2]: b = 4

In [3]: a > b
Out[3]: False

In [4]: a < b
Out[4]: True

In [5]: assert a == b
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-5-46f3032e8f4c> in <module>()
----> 1 assert a == b

AssertionError: 

In [6]: assert a > b
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-6-418b25926324> in <module>()
----> 1 assert a > b

AssertionError: 

In [7]: assert a < b

当条件为真的时候就执行上面。

raise 与 assert 的区别:

raise 是主动抛出异常,就是没有异常的也可以抛出异常;而assert是当条件不满足是抛出异常。

3. 习题

3.1 自己构造一个报错的场景,并模仿上面的例子进行一个报错分析。

avatar

错误原因:是整型和字符串类型之间不能做减法的操作。

用try . . . except捕获异常 avatar

3.2 结合异常处理,确保打开文件后的正常关闭。

如果我用w模式正常打开文件,然后write时候如果报错呢?那么我怎么正常关闭文件? avatar