Exception(异常)
当遇到异常的条件时,Python使用exception对象来描述。当遭遇一个错误的时候,程序就抛出一个异常,如果没有来处理此类异常的策略的话,程序将会以一个traceback的方式终止,代码如下:
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
每个异常都是一个类的实例(上例中是ZeroDivisionError),有许多方法来抛出和捕捉异常,最好要处理这些异常,而不是让程序崩溃。
抛出异常
>>> raise Exception
Traceback (most recent call last):
File "<stdin>", line 1, in ?
Exception
>>> raise Exception('hyperdrive overload')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
Exception: hyperdrive overload
列出所有的Python自带的异常类型
>>> import exceptions
>>> dir(exceptions)
['ArithmeticError', 'AssertionError', 'AttributeError', ...]
这些异常都可以用raise语句抛出
>>> raise ArithmeticError
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ArithmeticError
Class Name | Description |
Exception | The base class for all exceptions |
AttributeError | Raised when attribute reference or assignment fails |
IOError | Raised when trying to open a nonexistent file (among other things) |
IndexError | Raised when using a nonexistent index on a sequence |
KeyError | Raised when using a nonexistent key on a mapping |
NameError | Raised when a name (variable) is not found |
SyntaxError | Raised when the code is ill-formed |
TypeError | Raised when a built-in operation or function is applied to an object of the wrong type |
ValueError | Raised when a built-in operation or function is applied to an object with the correct type, but with an inappropriate value |
ZeroDivisionError | Raised when the second argument of a division or modulo operation is zero |
定义自己的异常类
class SomeCustomException(Exception): pass
捕获异常
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!"
在函数中抛出的异常,可以传递到调用它的地方之外,如果函数不能捕获异常,那么这个异常则会像冒泡一样,一直传递到程序的顶端,这意味着,try/catch语句可以处理其他函数的异常。
如果一个异常,无法处理,可以利用raise语句继续将它抛出交给其他的地方来捕获。如下代码:
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
全部的当muffled值为True和false的代码如下:
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
捕获多个异常
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?"
如果对多个异常有相同的处理方法,可以把多个异常整合到一个代码块中,而异常则都放在一个tuple中:
try:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
print x/y
except (ZeroDivisionError, TypeError, NameError):
print 'Your numbers were bogus...'
如果你想在except语句中访问异常对象,只需要将参数改变成两个就可以了,如下。当你想在捕获多个异常的时候,不影响系统,而又想将错误记录在log文件的话,这个方法很有用。
try:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
print x/y
except (ZeroDivisionError, TypeError), e:
print e
注意, Python 3.0中,要写成这个样子
except (ZeroDivisionError, TypeError) as e.
如果你想要捕获所有的错误,那么你可以这样写:
ry:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
print x/y
except:
print 'Something wrong happened...'
但是这样做风险很大,因为它会忽略一切异常,比如Control+C的手动结束,sys.exit(),等等。所以,做好将它写成如下的形式:
except Exception, e
然后对e进行某些检测。
某些情况下,如下代码可以让程序一直正确运行,直到碰到异常
try:
print 'A simple task'
except:
print 'What? Something went wrong?'
else:
print 'Ah... It went as planned.'
如下的代码表示,只有没有异常的情况下程序才会结束,如果有异常,则输出是什么异常
while True:
try:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
value = x/y
print 'x/y is', value
except Exception, e:
print 'Invalid input:', e
print 'Please try again'
else:
break
finally语句
finally语句在发生异常的时候才执行,一半是用来处理后事的^ ^
x = None
try:
x = 1/0
finally:
print 'Cleaning up...'
del x
finally语句中的东西在程序崩溃前执行
你也可以将这四个东西放在同一个语句快中
try:
1/0
except NameError:
print "Unknown variable"
else:
print "That went well!"
finally:
print "Cleaning up."