python入门Python爬虫作业大数据 爬虫Python AI Sql

学习笔记——Python」Python 的错误和异常处理

2018-05-10  本文已影响24人  Python资料

到现在为止,还没怎么提过错误消息,不过如果你试过一些示例,可能会看到一些。有两种不同类型的 错误:语法错误和例外

Table of Contents

1 语法错误

2 异常(Exceptions)

3 处理异常

4 raise 异常

5 用户自定义异常

6 定义清除(clean-up)操作

7 预定义的 清除(Clean-up) 操作

1语法错误

语法错误可能是你还在学习python时最为常见的错误,例如

>>>whileTrueprint"hi~"File"", line 1whileTrueprint"hi~"^SyntaxError: invalid syntax

有一个箭头指向最早发现错误的地方,这里指向了print,因为Ture后面少了冒号

2异常(Exceptions)

即使语句和表达式语法正确,在执行时也可能出现错误,这种错误称为异常(Exceptions)。 异常并不都是致命的,你马上会学到如何处理他们。 许多异常程序都不处理,而是返回一个错误消息,例如:

>>> 10 * (1/0)Traceback (most recent call last):  File"", line 1,inZeroDivisionError: integer divisionormodulo by zero>>> 4 + git*3Traceback (most recent call last):  File"", line 1,inNameError: name'git'isnotdefined>>>'2'+ 1Traceback (most recent call last):  File"", line 1,inTypeError: cannot concatenate'str'and'int'objects>>>

错误消息的最后一行就是异常消息,冒号前是异常的类型。上面的 ZeroDivisionError, NameError, TypeError, 都是系统内置的异常。

3处理异常

可以自己编写程序来处理异常,比如下面这个例子,它会返回异常,直到用户输入有效数据为止。

>>>whileTrue:...try:...        x =int(raw_input("Please enter a number: "))...break...exceptValueError:...print"Oops! That was no valid number. Try again..."... Please enter a number: xOops! That was no valid number. Try again...Please enter a number: 32xOops! That was no valid number. Try again...Please enter a number: 038

使用 try 和 except ExceptionName 来处理异常

如果没有异常产生,except 段会被跳过

如果某处有异常产生,后面的语句会被跳过,如果产生的异常类型和except后的类型一致,except后的语句会被执行

如果发生异常,但和except后的类型不一致,异常会传递到try语句外面,如果没有相应处理,那么就会打印出像上 一个例子那样的信息。

一个try语句可能有多个except与之对应,分别处理不同类型的异常,最多只有一种处理会被执行。一个except可以包含多 个类型名,比如:

...except(RuntimeError,TypeError,NameError):...pass

注意上面的三种异常类型,必须用括号把它们括起来,因为在现代python中, except ValueError, e 的意思是 except ValueError as e:(后面会讲这是什么意思)

最后一个except一般不指定名字,用于处理其余情况

importsystry:    f =open('myfile.txt')    s = f.readline()    i =int(s.strip())exceptIOErrorase:print"I/O error({0}): {1}".format(e.errno, e.strerror)exceptValueError:print"Could not convert data to an integer."except:print"Unexpected error:", sys.exc_info()[0]raise

try..except 语句还可以选择使用else,例如

forarginsys.argv[1:]:try:        f =open(arg,'r')exceptIOError:print'cannot open', argelse:printarg,'has',len(f.readlines()),'lines'f.close()

需要注意,一旦使用else,每个except后都要有else,这种方式用于需要指定某一异常不出现时执行什么操作。

except子句可以在异常名后指定参数,这些参数被存储在异常实例产生时的 instance.arg

>>>try:...raiseException('spam','eggs')...exceptExceptionasinst:...printtype(inst)...printinst.args...printinst...    x, y = inst.args...print'x =', x...print'y =', y... ('spam','eggs')('spam','eggs')x= spamy= eggs

异常处理不仅仅处理直接在try中出现的异常,还可以处理在try中调用函数的异常

>>>defmdiv():...    x = 1/0... >>>try:...    mdiv()...exceptZeroDivisionErrorasdetail:...print'Handling run-time error:', detail... Handling run-time error: integer divisionormodulo by zero

4raise 异常

raise 语句允许强制一个异常发生

>>>raiseNameError('hi,there')Traceback (most recent call last):  File"", line 1,inNameError: hi,there

raise 的参数必须是一个异常实例或者一个异常类

5用户自定义异常

程序可以通过创建一个异常类来命令一个新的异常,这个异常类需要通过直接或者间接的方式由 Exception 类派生。

>>>classMyError(Exception):...def__init__(self, value):...self.value = value...def__str__(self):...returnrepr(self.value)... >>>try:...raiseMyError(1+5)...exceptMyErrorase:...print'My exception occurred, value:', e.value... My exception occurred, value: 6>>>raiseMyError('oops!')Traceback (most recent call last):  File"", line 1,in__main__.MyError:'oops!'

在上面的例子中,__ init __ (), 覆盖了默认的 init 函数,新的行为创建了 value 属性, 替换了原有的 创建args属性的行为。

其它类可以做的事情,通过定义Exception类都可以完成。但是Exception类总是被设计地非常简单, 它们提供一些属性,这样错误处理时就可能方便地提取出这些属性。 当设计一个模块处理多种异常时,常常先定义一个基本的类,其它类在此基础上处理一些特殊情况。

classError(Exception):"""Base class for exceptions in this module."""passclassInputError(Error):"""Exception raised for errors in the input.    Attributes:        expr -- input expression in which the error occurred        msg  -- explanation of the error    """def__init__(self, expr, msg):self.expr = exprself.msg = msgclassTransitionError(Error):"""Raised when an operation attempts a state transition that's not    allowed.    Attributes:        prev -- state at beginning of transition        next -- attempted new state        msg  -- explanation of why the specific transition is not allowed    """def__init__(self, prev,next, msg):self.prev = prevself.next =nextself.msg = msg

6定义清除(clean-up)操作

try语句还可以定义清除操作,用于无论任何时候都需要被执行的语句。

>>>try:...raiseKeyboardInterrupt...finally:...print'Goodbye, world!'... Goodbye, world!Traceback (most recent call last):  File"", line 2,inKeyboardInterrupt

无论是否发生异常,finally后的语句在离开try之前都会被执行。

下面看一个复杂点的例子,

>>>defdivide(x, y):...try:...        result = x / y...exceptZeroDivisionError:...print"division by zero!"...else:...print"result is", result...finally:...print"excecuting finally clause"... >>> divide (3,2)resultis1excecutingfinallyclause>>> divide (3,0)division by zero!excecutingfinallyclause>>> divide ("3","1")excecutingfinallyclauseTraceback (most recent call last):  File"", line 1,in  File"", line 3,individeTypeError: unsupported operandtype(s)for/:'str'and'str'

在实例应用中,finally

7预定义的 清除(Clean-up) 操作

一些对象预先定义了清除操作,当不再需要对象时这些清除操作会被执行,无论使用此对象的操作是否成功。

例如下面的例子:

forlineinopen("myfile.txt"):printline,

上述例子的问题在于,程序执行完后,文件对象仍然没有关闭。

with语句可以使得file这样的对象被及时正确合理地清除

withopen("myfile.txt")asf:forlineinf:printline,

上一篇 下一篇

猜你喜欢

热点阅读