什么是异常
python用异常对象(exception object)来表示异常情况。遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,程序就会用所谓的 回溯(Traceback, 一种错误信息)终止执行
>>> 1/0
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
1/0
ZeroDivisionError: integer division or modulo by zero
>>>
按自己的方式出错
raise语句
>>> raise Exception
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
raise Exception
Exception
>>> raise Exception(‘hyperdrive overload‘)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
raise Exception(‘hyperdrive overload‘)
Exception: hyperdrive overload
>>>
查看exceptions模块中的内建异常
>>> 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__‘]
>>>
>>> raise ArithmeticError
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
raise ArithmeticError
ArithmeticError
>>>
自定义异常类
尽管内建的异常类已经包括了大部分的情况,而且对于很多要求都已经足够了,但有些时候还是需要创建自己的异常类。
和常见其它类一样----只是要确保从Exception类继承,不管直接继承还是间接继承。像下面这样:
>>> class SomeCustomException(Exception):
pass
当然,也可以为这个类添加一些方法。
捕捉异常
我们可以使用 try/except 来实现异常的捕捉处理。
假设创建了一个让用户输入两个数,然后进行相除的程序:
x=input(‘Please enter the first number: ‘)
y=input(‘Please enter the second number: ‘)
print x/y
Please enter the first number: 10
Please enter the second number: 0
Traceback (most recent call last):
File "F:/python/myDemo/except.py", line 3, in <module>
print x/y
ZeroDivisionError: integer division or modulo by zero
>>>
为了捕捉异常并做出一些错误处理,可以这样写:
try:
x=input(‘Please enter the first number: ‘)
y=input(‘Please enter the second number: ‘)
print x/y
except ZeroDivisionError:
print ‘The second number can\‘t be zero‘
------------
Please enter the first number: 10
Please enter the second number: 0
The second number can‘t be zero
>>>
假如,我们在调试的时候引发异常会好些,如果在与用户的进行交互的过程中又是不希望用户看到异常信息的。那如何开启/关闭 “屏蔽”机制?
class MuffledCalculator:
muffled=False
def calc(self,expr):
try:
return eval(expr)
except ZeroDivisionError:
if self.muffled:
print ‘Division by zero is illegal‘
else:
raise
------------
>>> calculator=MuffledCalculator()
>>> calculator.calc(‘10/2‘)
5
>>> calculator.calc(‘10/0‘)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
calculator.calc(‘10/0‘)#没有屏蔽
File "F:/python/myDemo/except.py", line 5, in calc
return eval(expr)
File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
>>> calculator.muffled=True
>>> calculator.calc(‘10/0‘)
Division by zero is illegal
>>>
不止一个except子句
如果运行上面的(输入两个数,求除法)程序,输入面的内容,就会产生另外一个异常:
enter the first number: 10
enter the second number: ‘hello,world‘
Traceback (most recent call last):
File "F:/python/myDemo/except.py", line 4, in <module>
print x/y
TypeError: unsupported operand type(s) for /: ‘int‘ and ‘str‘
>>>
因为except子句只检查ZeroDivisionError异常,所以这个异常就错过了检查,为了捕捉这个异常,我们可以在try/except语句加一个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‘
except TypeError:
print ‘That wasn\‘t a number,was it?‘
--------------------------
>>>
enter the first number: 10
enter the second number: ‘hello,world!‘
That wasn‘t a number,was it?
>>>
用一个块捕捉两个异常
try:
x=input(‘enter the first number: ‘)
y=input(‘enter the second number: ‘)
print x/y
捕捉对象
try:
x=input(‘enter the first number: ‘)
y=input(‘enter the second number: ‘)
print x/y
except (ZeroDivisionError,TypeError,NameError),e:
print e
-----------------
>>>
enter the first number: 10
enter the second number: 2
5
>>>
>>> ================================ RESTART ================================
>>>
enter the first number: 10
enter the second number: 0
integer division or modulo by zero
>>> ================================ RESTART ================================
>>>
enter the first number: 10
enter the second number: ‘hello,world‘
unsupported operand type(s) for /: ‘int‘ and ‘str‘
>>>
真正的全捕捉
就算程序能处理好几种异常,但有些异常还是会处理不到,例如上个除法的例子,输入空格:
enter the first number:
Traceback (most recent call last):
File "F:/python/myDemo/except.py", line 2, in <module>
x=input(‘enter the first number: ‘)
File "<string>", line 0
^
SyntaxError: unexpected EOF while parsing
>>>
因此我们可以在except子句中忽略所有异常类
try:
x=input(‘enter the first number: ‘)
y=input(‘enter the second number: ‘)
print x/y
except:
print ‘Something wrong happend...‘
--------------
>>>
enter the first number: 10
enter the second number: 0
Something wrong happend...
>>> ================================ RESTART ================================
>>>
enter the first number:
Something wrong happend...
>>>
万事大吉
while True:
try:
x=input(‘Enter the first number: ‘)
y=input(‘Enter the second number: ‘)
value=x/y
print ‘x/y is ‘,value
except:
print ‘Invalid input .Please try again.‘
else:
break
--------------------
Enter the first number: 10
Enter the second number: 0
Invalid input .Please try again.
Enter the first number: 10
Enter the second number: ‘hello‘
Invalid input .Please try again.
Enter the first number: 10
Enter the second number: 2
x/y is 5
>>>
最后
最后finally子句用来对可能的异常进行清理,它和try子句联合使用
x=None
try:
x=1/0
finally:
print ‘Cleaning up...‘
del x
-------------
Cleaning up...
Traceback (most recent call last):
File "F:/python/myDemo/except.py", line 3, in <module>
x=1/0
ZeroDivisionError: integer division or modulo by zero
>>>
try:
1/0
except NameError:
print ‘Unknown variable‘
else:
print ‘That went well!‘
finally:
print ‘Cleaning up.‘
异常和函数
如果异常在函数内没被处理,它就会传播至函数调用的地方,直到程序带着堆栈跟踪终止
def faulty():
raise Exception(‘Someting is wrong‘)
def ignore_exception():
faulty()
def handle_exception():
try:
faulty()
except:
print ‘Exception handled‘
----------------------------
>>> ignore_exception()
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
ignore_exception()
File "F:/python/myDemo/except.py", line 4, in ignore_exception
faulty()
File "F:/python/myDemo/except.py", line 2, in faulty
raise Exception(‘Someting is wrong‘)
Exception: Someting is wrong
>>> handle_exception()
Exception handled
>>>