异常是一个事件,改事件会在程序执行过程当中发生,影响程序的正常执行,通常状况下,在python中没法处理程序时就会发生异常,异常时Python的一个对象,表示一个错误,当Python脚本发生异常时,咱们须要捕获并处理异常,不然程序就会终止执行。python
当Python脚本出现异常的时候咱们怎么处理那?
就如咱们使用的工具出现了一点毛病,咱们能够想办法修理好它,程序也是同样,以前的前辈们通过不断的积累与思考,创造了不少好得方法处理程序中出现的异常,本章咱们就讲一下使用try语句处理异常。
首先咱们来讲一下try语句的语法:
try语句与except 相结合使用,此语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理,若是不想在发生异常时结束程序,只须要在try语句中捕获异常便可express
try: <代码块>
except <异常名字>
print(‘语句’) 实例以下: def func(): try: a = x/y print('a=',a) return a eccept Exception: print('程序出现异常,异常信息:被除数为0')
在Python中使用raise语句抛出一个指定的异常,咱们可使用类或实例参数调用raise语句引起异常。
实例以下:app
class EvaException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msg try: raise EvaException('类型错误') except EvaException as e: print(e)
咱们前面说了怎么处理一个异常的状况,若是涉及到多个,咱们该怎么处理那?
在Python中支持一个try/except语句处理多个异常,语法以下:
ide
try: <语句> except <异常名字>: print(‘异常说明’) except <异常名字>: print(‘异常说明’) try语句的工做方式以下:
首次执行try中语句块,若是没有发生异常,则忽略except中的字句,try语句中的代码块执行后结束。若是try语句中的代码块出现异常,try中的剩余语句则会被忽略,
若是异常和eccept中的异常名字一直,相应的except语句就会被执行。若是一个异常也没有匹配,这个异常就会传递给上层的try语句中,一个语句可能包含第一个except语句,
分别处理不一样的异常,可是最多只有一个分支会执行。
try:
#a
#1/0
dic = {1:2}
dic[3]
except NameError:
print('名字没有定义,报错了')
except ZeroDivisionError:
print('0不能当作除数,报错了')
except KeyError:
print('没有这个key')
咱们若是程序执行完异常后还想作其余的事情怎么办?
这时咱们就能够用到异常中的else了,具体语法以下:
工具
try: <语句>
except <异常名字> : <语句>
except <异常名字>: <语句>
else: <语句> #(try语句中没有异常后执行此段代码)
若是在try语句中执行没有发生异常,就会执行else语句,使用else语句比把全部语句都放在try字句里面更好,这样能够避免一些意想不到的而except有没有捕获到的异常: def func(x,y): try: a = x/y except : print('Error,happened') else: print('It went as execpt') func(2,1)
你能够经过建立一个新的exception类来拥有本身的异常。异常应该继承自 Exception 类,或者直接继承,或者间接继承,例如:oop
class MyError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) try: raise MyError(2*2) except MyError as e: print('My exception occurred, value:', e.value) My exception occurred, value: 4
raise MyError('oops!') Traceback (most recent call last): File "<stdin>", line 1, in ? main__.MyError: 'oops!' 在这个例子中,类 Exception 默认的 __init__() 被覆盖。 当建立一个模块有可能抛出多种不一样的异常时,一种一般的作法是为这个包创建一个基础异常类,而后基于这个基础类为不一样的错误状况建立不一样的子类: class Error(Exception): """Base class for exceptions in this module."""
pass
class InputError(Error): """Exception raised for errors in the input. Attributes: expression -- input expression in which the error occurred message -- explanation of the error """
def __init__(self, expression, message): self.expression = expression self.message = message class TransitionError(Error): """Raised when an operation attempts a state transition that's not allowed. Attributes: previous -- state at beginning of transition next -- attempted new state message -- explanation of why the specific transition is not allowed """
def __init__(self, previous, next, message): self.previous = previous self.next = next self.message = message 大多数的异常的名字都以"Error"结尾,就跟标准的异常命名同样。
try 语句还有另一个可选的子句,它定义了不管在任何状况下都会执行的清理行为。 例如:this
>>> try: ... raise KeyboardInterrupt ... finally: ... print('Goodbye, world!') ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in <module> KeyboardInterrupt 以上例子无论 try 子句里面有没有发生异常,finally 子句都会执行。 若是一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后再次被抛出。 下面是一个更加复杂的例子(在同一个 try 语句里包含 except 和 finally 子句): >>> def divide(x, y): try: result = x / y except ZeroDivisionError: print("division by zero!") else: print("result is", result) finally: print("executing finally clause") >>> divide(2, 1) result is 2.0 executing finally clause >>> divide(2, 0) division by zero! executing finally clause >>> divide("2", "1") executing finally clause Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 3, in divide TypeError: unsupported operand type(s) for /: 'str' and 'str' 预约义的清理行为 一些对象定义了标准的清理行为,不管系统是否成功的使用了它,一旦不须要它了,那么这个标准的清理行为就会执行。 这面这个例子展现了尝试打开一个文件,而后把内容打印到屏幕上: for line in open("myfile.txt"): print(line, end="") 以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并无被关闭。 关键词 with 语句就能够保证诸如文件之类的对象在使用完以后必定会正确的执行他的清理方法: with open("myfile.txt") as f: for line in f: print(line, end="") 以上这段代码执行完毕后,就算在处理过程当中出问题了,文件 f 老是会关闭。
异常名称 | 描述 |
---|---|
BaseException | 全部异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(一般是输入^C) |
Exception | 常规错误的基类 |
StopIteration编码 |
迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 全部的内建标准异常的基类 |
ArithmeticError | 全部数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (全部数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操做系统错误的基类 |
IOError | 输入/输出操做失败 |
OSError | 操做系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 通常的运行时错误 |
NotImplementedError | 还没有实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 通常的解释器系统错误 |
TypeError | 对类型无效的操做 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造未来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提高为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |