python——异常

一、什么是异常

1.错误

从软件方面来说,错误是语法或是逻辑上的。错误是语法或是逻辑上的

语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译。这些些错误必须在程序执行前纠正。

当程序的语法正确后,剩下的就是逻辑错误了。逻辑错误可能是由于不完整或是不合法的输入所致;

在其它情况下,还可能是逻辑无法生成、计算、或是输出结果需要的过程无法执行。这些错误通常分别被称为域错误和范围错误。

当python检测到一个错误时,python解释器就会指出当前流已经无法继续执行下去。这时候就出现了异常。

2.异常

对异常的最好描述是:它是因为程序出现了错误而在正常控制流以外采取的行为

这个行为又分为两个阶段:首先是引起异常发生的错误,然后是检测(和采取可能的措施)阶段。

第一阶段是在发生了一个异常条件(有时候也叫做例外的条件)后发生的。

只要检测到错误并且意识到异常条件,解释器就会发生一个异常。引发也可以叫做触发,抛出或者生成。解释器通过它通知当前控制流有错误发生。

python也允许程序员自己引发异常。无论是python解释器还是程序员引发的,异常就是错误发生的信号。

当前流将被打断,用来处理这个错误并采取相应的操作。这就是第二阶段。

对于异常的处理发生在第二阶段,异常引发后,可以调用很多不同的操作。

可以是忽略错误(记录错误但不采取任何措施,采取补救措施后终止程序。)或是减轻问题的影响后设法继续执行程序。

所有的这些操作都代表一种继续,或是控制的分支。关键是程序员在错误发生时可以指示程序如何执行。

python用异常对象(exception object)来表示异常。遇到错误后,会引发异常。

如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(traceback)终止执行,就像下面这样。

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

类似python这样支持引发和处理异常的语言,可以让开发人员在错误发生时更直接的控制它们。

程序员不仅有了检测错误的能力,还可以在它们发生时采取更可靠的补救措施。由于有了运行时管理错误的能力,应用程序的健壮性有了很大的提高。

二、python中常见的异常

在python2中可以通过一个模块来查看所有的内置异常,而在python3中就无法查看。

>>> import exceptions
>>> dir(exceptions)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'EnvironmentError', 'Exception', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__doc__', '__name__', '__package__']

下面介绍介几个使用的比较频繁的异常。

1.NameError:尝试访问一个未申明的变量。

>>> foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

NameError表示我们访问了一个没有初始化的变量

任何可访问的变量必须在名称空间里列出,访问变量需要由解释器进行搜索,如果请求的名字没有在任何名称空间里找到,那么就会生成一个NameError异常。

2.ZeroDivisionError:除数为0.

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

任何一个数值被零除都会导致ZeroDivisionError异常。

3.SyntaxError:python解释器语法错误。

>>> for i in li:
...     print i
  File "<stdin>", line 2
    print i
          ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(i)?

SyntaxError异常是唯一不是在运行时发生的异常

它代表python代码中有一个不正确的结构,在他改正之前程序无法运行。

这些错误一般都是在编译时发生的,python解释器无法把你的脚本转化成python字节代码。

4.IndexError:请求的索引超出范围。

>>> li
[1, 2, 3, 4]
>>> li[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

5.KeyError:请求一个不存在的字典关键字。

>>> dict1 = {"name":'kebi',"sex":'boy'}
>>> dict1['age']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'age'

6.IOError/FileNotFoundError:输入/输出错误

类似尝试打开一个不存在的磁盘文件一类的操作会引发一个操作系统输入/输出错误。

在python2中引发IOError异常;在python3中引发/FileNotFoundError异常。

#在python2中
>>> f = open('helo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'helo'

#在python3中
>>> f = open('blah')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'blah'

7.AttributeError:尝试访问未知的对象属性。

>>> class myClass(object):
...     pass
... 
>>> myInst = myClass()
>>> myInst.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'myClass' object has no attribute 'foo'

三、检测和处理异常

异常可以通过try语句来检测。任何在try语句块里的代码都会被监测,检查有无异常发生。

一个try语句可以对应多个expect语句,但只能对应一个finally子句,或是一个try-expect-finally复合语句。

你可以使用try-expect语句检测和处理异常,你也可以添加一个可选的else子句处理有没有探测到异常的执行代码。

而finally只允许检测异常并做一些必要的清楚工作(无论发生错误与否),没有任何异常处理设施。

1.try-expect语句

try-expect语句(以及其更复杂的形式)定义了进行异常监控的一段代码,并提供了处理异常的机制。

>>> try:
...     a   #监控这里的异常
... except NameError:
...     print("警告")  #异常处理代码
... 
警告

正常情况下:

>>> try:
...     a=1
... except NameError:
...     print("警告")
... 

在程序运行时,解释器尝试执行try块里所有的代码,如果代码完成后没有发生异常,执行流会忽略except语句继续执行。

而当except语句所制定的异常发生后,我们保存了错误的原因,控制流会立即跳转到对应的处理器(try子句的剩余语句会被忽略。)

2.多个expect子句

try:
    x = int(input("frist num>>>"))
    y = int(input("second num>>>"))
    print(x/y)
except ValueError:
    print("只能是数字")
except ZeroDivisionError:
    print("除数不能为0")

#执行结果
frist num>>>a
只能是数字

frist num>>>2
second num>>>0
除数不能为0

3.用一个块捕捉多个异常

except语句在处理多个异常时要求异常被放在一个元祖里。

try:
    x = int(input("frist num>>>"))
    y = int(input("second num>>>"))
    print(x/y)
except (ValueError,ZeroDivisionError):
    print("输入有误")

#执行结果
frist num>>>a
输入有误

4.捕获所有异常

使用Exception可以截获所有异常。

try:
    x = int(input("frist num>>>"))
    y = int(input("second num>>>"))
    print(x/y)
except Exception as e:
    print("输入有误",e)

#执行结果
frist num>>>tyui
输入有误 invalid literal for int() with base 10: 'tyui'

注意:

python提供给程序员的try-expect语句是为了更好的跟踪潜在的错误并在代码里准备好处理异常的逻辑。

但是尽量不要把大片的代码装入try-except中然后使用pass忽略掉错误。

原文地址:https://www.cnblogs.com/yangmingxianshen/p/7840754.html