什么是异常
Python用异常对象来表示异常情况,遇到错误后会引发异常。如果异常对象未被处理或捕捉,程序就会用所谓的回溯终止执行
按自己的方式出错
raise语句
使用一个类(Exception及其子类)或者类实例调用raise语句可以引发异常。
Python内建异常可以在exceptions模块中找到,可以使用dir列出模块内容
>>> 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__']
自定义异常类
自定义异常类只需确保直接或间接从Exception类继承即可
捕捉异常
可以用try/except语句来实现捕捉异常
>>> try:
x = input('Enter the first number')
y = input('Enter the second number')
print x / y
except ZeroDivisionError:
print "The second number can't be zero!"
Enter the first number 10
Enter the second number 0
The second number can't be zero!
如果想要捕获多个异常,多个异常可以以元祖的新式作为except的第一个参数
>>> try:
x = input('Enter the first number')
y = input('Enter the second number')
print x / y
except (ZeroDivisionError, TypeError, NameError):
print "number illegal"
Enter the first number 10
Enter the second number 'a'
number illegal
可以有多个except字句,except可以有第二个参数,即:e
>>> try:
x = input('Enter the first number')
y = input('Enter the second number')
print x / y
except ZeroDivisionError, e:
print 'Exception one!'
print e
except TypeError, e:
print 'Exception two'
print e
Enter the first number 10
Enter the second number 'a'
Exception two
unsupported operand type(s) for /: 'int' and 'str'
Python3.0中,except字句会被写作except(ZeroDivisionError, TypeError)as e
真正的全捕捉
如果想用一段代码捕捉所有异常,可以在字句中忽略所有异常类,但不提倡
万事大吉
有些情况下,没有发生异常时应该执行一段代码,可以像条件、循环语句那样,给try/except语句加else字句来实现。
百分百捕捉异常时不可能的因为try/except语句中的代码可能会出问题,比如使用旧风格的字符串异常或者自定义的异常类不是Exception子类
最后
最后是finally字句,可以在可能的异常后进行清理,Python2.5之前,一个try语句中不能同时使用except和finally子句,但是一个子句可以放置在另一个子句里面,Python2.5及以后的版本中,可以尽情地组合这些子句。
>>> try:
10/0
except NameError:
print "Unknown variable"
except ZeroDivisionError:
print "divisor can't be zerro"
else:
print 'went well'
finally:
print 'clean up.'
divisor can't be zerro
clean up.
在很多情况下,使用try/except语句比使用if/else会更自然(更Python化),应该尽可能培养使用try/except的习惯。
try/except语句在Python中的表现可以用海军少将Crace Hopper的妙语解释:“请求宽恕易于请求许可”,即在做一件事情的时候去处理可能的错误,而不是在做事情之前进行大量的排查,这个策略可以总结为习语“看前就跳”