python基础教程----异常

来源:互联网 发布:ghost软件有windows 编辑:程序博客网 时间:2024/05/17 05:55

1.什么是异常

Python用异常对象来表示异常,遇到错误后,会引发异常,如果异常对象并未被处理或捕捉,程序会用所谓的回溯终止执行。

2.按自己的方式出错

如何引发异常,甚至创建自己的异常类型

2.1raise语句

为了引发异常,可以使用一个类(Exception子类)或实例参数调用raise语句,使用类时,程序会自动创建实例。

>>> raise Exception 引发了一个没有任何有关错误信息的普通异常

>>> raise Exception(‘hyperdiveoverload’) 添加了一些hyperdiveoverhead错误信息

内建异常可以使用交互式解释权分析,可在exception模块(和内建的命名空间)中找到,可以使用dir函数列出模块的内容

>>> import exceptions

>>> dir(exceptions)

一些内建异常

Exception 所以异常的基类

AttributeError 特性引用或赋值失败时引发

IOError 试图打开不存在文件(包括其他情况)时引发

IndexError 在使用序列中不存在的索引时引发

KeyError 在使用映射中不存在的键时引发

NameError 在找不到名字(变量)时引发

SyntaxError 在代码为错误形式时引发

TypeError 在内建操作或函数应用于错误类型的对象时引发

ValueError 在内建操作或函数应用于正确类型的对象,但该对象使用不合适的值时引发

ZeroDivisionError 在除法或者模除操作的第二个参数为0时引发


2.2自定义异常类

只要确保从Exception类继承

class someCustomException(Exception): pass

3.捕捉异常

try/catch处理(捕捉,诱捕)

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:

Print “The second number can’t be zero”

如果没有捕捉异常,它会被“传播”到调用的函数中,如果在那里依然没有捕捉,这些异常就会‘浮到’程序的最顶层,也就是说你可以捕捉到其他人的函数中所引发的异常

如果捕捉到了异常,但是又想重新引发它(即需要传递异常),那么可以调用不带参数的raise(还能在捕捉到异常时显示地提供具体异常)

能“屏蔽”ZeroDivisionError(初零错误)的计算器类,如果这个行为被激活,那么计算器就会打印错误信息,而不是让异常传播,如果在与用户进行交互的过程中使用,那么就有用了,但是如果在程序内部使用,引起异常会更好写。因此‘屏蔽’机制就可以关掉了

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

如果初零行为发生而屏蔽机制被打开,那么calc方法(隐式地)返回None,即如果打开了屏蔽机制,那么就不应该依赖返回值

>>> calculator = MuffledCalculator()

>>> calculator.calc(‘10/2’)

5

>>> calculator.calc(‘10/0’)

Traceback (most recent call last):

File “<stdin>”. Line 1. In ?

File”MuffledCalculatro.py”.line 6. in calc

Return eval(expr)

FIle “<string>”. Line 0. In?

ZeroDivisionError: integer division or module byzero

>>> calculator.muffled = True

>>> calculator.calf(‘10/0’)

Division by zero is illegal

当计算器没有打开屏蔽机制时,ZeroDivisionError被捕捉但已传递了

4.不止一个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?”

5.用一个块捕捉两个异常

作为元组列出,注意Exception字句外面的圆括号

try:

x = input(‘Enter the first number:’)

y = input(‘Enter the second number:’)

print x/y

except (ZeroDivisionError, TypeError, NameError):

Print “The second number can’t be zero”

6.捕捉对象

如果希望在except字句中访问异常对象本身,可以使用两个参数(注意就算要捕捉到多个异常,也只需向except字句提供一个参数---一个元组),如想让程序继续运行,但是又因为某种原因想记录下错误(比如只是打印给用户看)

try:

x = input(‘Enter the first number:’)

y = input(‘Enter the second number:’)

print x/y

except (ZeroDivisionError, TypeError), e

Print e

7.真正的全捕捉

try:

x = input(‘Enter the first number:’)

y = input(‘Enter the second number:’)

print x/y

except

Print “Something wrong happened”

这样捕捉是危险的,因为它会隐藏所以程序员未想到并且未做好准确处理的错误

同时会捕捉用户终止执行的Ctrl+C,以及用sys.exit函数终止程序的企图等

8.万事大吉

使用else字句

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:

print ‘Invalid input. Please try again’

else:

break

循环只在没有异常发生的情况下才会退出

9.最后finally字句

可以用了在可能的异常后进行清理,和try字句联合使用

x = None

try:

x = 1 / 0

finally:

print ‘Cleaning up...’

del x

try字句之前初始化x的原因是如果不这样做,由于ZeroDivisionError的存在,x就永远不会被赋值,这样会导致在finally字句中使用del删除它的时候产生异常,而且这个异常无法捕捉

因为使用del语句删除一个比那里是非常不负责的清理手段,所以finally子句用于关闭文件或者网络套接字时非常有用

还可以再同一条语句中组合使用try,except, finallyelse

try:

1/0

except NameError:

print “Unknown variable”

else:

print”That went well”

finally:

print “Cleaning up”

10.异常和函数

异常和函数能很自然的一起工作,如果异常在函数内引发而不被处理,它就会传播至(浮到)函数调用的地方,如果在那里也没有处理异常,它就会继续传播,一直到达主程序(全局作用域),如果那里没有异常处理程序,程序会带着堆栈跟踪中止

>>> def faulty():

raise exception(‘Something is wrong’)

>>> def ignore_exception():

faulty()

>>> def handle_exception():

try:

faulty()

Except:

print ‘Exception handled’

>>> ignore_exception()

Traceback (most recent call last):

File ‘<stdin>’. Line 1. In?

File ‘<stdin>’. Line 2. Inignore_exception

File ‘<stdin>’. Line 1. In faulty

Exception: Something is wrong

>>> handle_exception()

Exception handled

faulty中产生的异常通过faultyignore_exception传播,最终导致了堆栈跟踪。

同样地,它也传播到handle_exception,但在这个函数中被try/catch语句处理

11.异常之禅

希望打印存储在特定的键下面的值,如果键不存在则什么也不做

try/catch假设键存在,不存在则捕捉异常,效率提升微乎其微


原创粉丝点击