错误

语法错误/解析错误,解释执行前发现,类SyntaxError .

异常

解释执行时发现的错误,类Exception ,用户可继承该类,定制异常。

异常基类实现了str方法,用来打印异常信息。、

额外知识

异常不是错误,异常甚至不是罕见的,异常是主观的,凡是不符合程序员预期的均可视作异常。

硬件异常 VS 程序异常

异常大致可以分为两种,一种是硬件异常,在程序之外由硬件触发的,如CPU发现除0错误、地址索引违规等,网卡发现数据,硬盘发现IO等,由OS或硬件异常处理机制处理;

另一种是程序异常,是由程序里面的代码主动触发的,比如非法输入、内存分配失败、文件IO错误等,由程序自身或者语言的runtime处理;

硬中断 VS 软中断

两者都是打断当前运行程序,转移控制权(程序指针)到指定内存地址的机制。

主要区别在于触发方和处理方式,硬中断由硬件触发,如鼠标、键盘,处理方式为跳转到指定内存地址(驱动程序),也可能需要硬件处理。

软中断由程序触发,如可通过int汇编指令触发,或者系统调用指令。

中断 VS 信号

中断可以视作CPU和OS之间沟通的手段,可以由CPU触发(页错误,除以零)、硬件设备触发、OS触发(系统调用),会打断CPU当前运行的指令,跳转到OS(或驱动等)设置的中断服务例程。

信号可以视作OS和进程之间沟通的手段,可以由OS发起,也可以由程序主动发起,由OS管理,OS将信号传递给指定的进程。

C VS C++

C语言没有结构化的异常处理机制,可以约定用返回值来区分正常调用和异常调用,来进行对应的处理。

Perhaps the most common form of exception-handling method used by software programmers is the “return-code” technique that was popularized as part of C and UNIX.

C++提供了结构化的异常处理机制,统一了异常处理的接口,异常可以在调用栈层层传递,也可以更细分的处理不同异常。

抛出异常

语法,关键字raise

raise ExceptionClass/ExceptionInstance

如果raise 后跟着异常类,会执行隐式无参初始化。

捕获异常

捕获异常关键字为except ,如果要捕获多个异常,可以显式指定要捕获的多个异常,也可以捕获它们共同的父类。

异常上下文

一个异常可以由另一个异常引起,即异常之间可以由上下文关系。有时候为了统一展示的目的,可能隐藏一些深层的异常,而由外层的异常进行展示。如,将关键字异常转换为属性异常,来隐藏底层是依赖字典实现的。

try:
    ...
except KeyError as exc:
    # raise AttributedError from exc
    raise  AttributeError from None

此时新异常是一个AttributeError ,其可以由原来的KeyError 触发,也可以由None触发,区别在于:

  • from exc:.__cause__ 属性和 .__context__属性均被设置为原来的exc,trace_back会打印新旧异常;
  • from None:仅.__context__属性被隐式设置为原来的异常(便于自省),旧异常被新异常替代,trace_back只会打印新异常;

警告

WarningExcetion的子类。

用途:想要警告用户,同时不终止程序(异常通常会终止),也不强制要求try...except... 子句。

print的区别:warnings 模块默认通过sys.stderr 打印警告信息,避免和标准输出混淆。

logging.warn()的区别:日志只是忠实地记录警告信息,Warning 重点在于警告用户(通常是开发者)做出修改。

触发警告

使用warnings.warn(msg, category=None, ...)

...
>>> warnings.warn('I am a warning!')
./warnings1.py:6: UserWarning: I am a warning!
warnings.warn('I am a warning!')

warnings.warn(...)category 参数用来指定警告类型,默认是UserWarning ,其他有DeprecationWarningSyntaxWarning等。

过滤警告

过滤警告就是对警告设置不同的处理方式,warnings 模块提供了过滤器接口,常见的有warnings.simplefilter(action, category=...) ,如:

warnings.simplefilter('error')
warnings.warn('Yikes!')

action参数可以指定不同的处理方式,category参数可以针对不同类型的警告定制处理方式。

action的选项:

  • “default” — display a warning the first time it is encountered
  • “error” — turn the warning into an exception
  • “ignore” — ignore the warning
  • “always” — always show the warning, even if it was displayed before
  • “module” — show the warning once per module
  • “once” — show the warning only once, throughout the program

因为警告是异常的子类,所以可以被正常raise

异常的层次

内置异常和警告的层级结构如下:

BaseException
 ├── BaseExceptionGroup
 ├── GeneratorExit
 ├── KeyboardInterrupt
 ├── SystemExit
 └── Exception
      ├── ArithmeticError
      │    ├── FloatingPointError
      │    ├── OverflowError
      │    └── ZeroDivisionError
      ├── AssertionError
      ├── AttributeError
      ├── BufferError
      ├── EOFError
      ├── ExceptionGroup [BaseExceptionGroup]
      ├── ImportError
      │    └── ModuleNotFoundError
      ├── LookupError
      │    ├── IndexError
      │    └── KeyError
      ├── MemoryError
      ├── NameError
      │    └── UnboundLocalError
      ├── OSError
      │    ├── BlockingIOError
      │    ├── ChildProcessError
      │    ├── ConnectionError
      │    │    ├── BrokenPipeError
      │    │    ├── ConnectionAbortedError
      │    │    ├── ConnectionRefusedError
      │    │    └── ConnectionResetError
      │    ├── FileExistsError
      │    ├── FileNotFoundError
      │    ├── InterruptedError
      │    ├── IsADirectoryError
      │    ├── NotADirectoryError
      │    ├── PermissionError
      │    ├── ProcessLookupError
      │    └── TimeoutError
      ├── ReferenceError
      ├── RuntimeError
      │    ├── NotImplementedError
      │    └── RecursionError
      ├── StopAsyncIteration
      ├── StopIteration
      ├── SyntaxError
      │    └── IndentationError
      │         └── TabError
      ├── SystemError
      ├── TypeError
      ├── ValueError
      │    └── UnicodeError
      │         ├── UnicodeDecodeError
      │         ├── UnicodeEncodeError
      │         └── UnicodeTranslateError
      └── Warning
           ├── BytesWarning
           ├── DeprecationWarning
           ├── EncodingWarning
           ├── FutureWarning
           ├── ImportWarning
           ├── PendingDeprecationWarning
           ├── ResourceWarning
           ├── RuntimeWarning
           ├── SyntaxWarning
           ├── UnicodeWarning
           └── UserWarning

<
Previous Post
迭代器和生成器
>
Next Post
音频处理