Python中的异常处理

Python中的异常事件:

  当Python遇到无法正常处理的事件时,便是异常发生的时候,Python将异常也当作一个对象,尽管他是出错的。当发生异常时候我们要捕获他,否则程序就会中断运行


Python标准异常:

异常名称 说明
NameError 语法错误,未声明/初始化对象 (没有属性)
EOFError 用户输入文件末尾标志EOF(Ctrl+d),Python3.2无
AssertionError 断言语句(assert)失败
KeyboardInterrupt 用户输入中断键(Ctrl+c)
KeyError 字典中查找一个不存在的关键字
ValueError 传入无效的参数
ZeroDivisionError 除数为零
AttributeError 尝试访问未知的对象属性
FloatingPointError 浮点计算错误
GeneratorExit generator.close()方法被调用的时候
ImportError 导入模块失败的时候
IndexError 索引超出序列的范围
MemoryError 内存溢出(可通过删除对象释放内存)
NotImplementedError 尚未实现的方法
OSError 操作系统产生的异常(例如打开一个不存在的文件)
OverflowError 数值运算超出最大限制
StopIteration 迭代器没有更多的值
RuntimeError 一般的运行时错误
SyntaxError Python的语法错误
IndentationError 缩进错误
SystemError Python编译器系统错误
SystemExit Python编译器进程被关闭
TypeError 不同类型间的无效操作
UnboundLocalError 访问一个未初始化的本地变量(NameError的子类)
UnicodeError Unicode相关的错误(ValueError的子类)
UnicodeEncodeError Unicode编码时的错误(UnicodeError的子类)
UnicodeDecodeError Unicode解码时的错误(UnicodeError的子类)
UnicodeTranslateError Unicode转换时的错误(UnicodeError的子类)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Python内置异常类的层次结构:

BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
      +-- StopIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning


 

Python错误处理方法:

不处理

  中断程序,并在终端显示异常信息。

处理异常

 我们可以使用try...except语句来处理异常,常把通常的语句放在try-块中,把异常处理语句放在except-块中。

  把所有可能引发错误的语句放在 try 块中,然后在 except 从句/块中处理所有 的错误和异常

 1 try:
 2  <statements>  #运行try语句块,并试图捕获异常
 3 except <name1>:
 4  <statements>  #如果name1异常发现,那么执行该语句块。
 5 except (name2, name3):
 6  <statements>  #如果元组内的任意异常发生,那么捕获它
 7 except <name4> as <variable>:
 8  <statements>  #如果name4异常发生,那么进入该语句块,并把异常实例命名为variable
 9 except:
10  <statements>  #发生了以上所有列出的异常之外的异常
11 else:
12 <statements>   #如果没有异常发生,那么执行该语句块
13 finally:
14  <statement>   #无论是否有异常发生,均会执行该语句块。

注意,

  else和finally是可选的;

  except从句可以专门处理单一错误或者异常,也可以处理一组包括在圆括号里面的异常;

  如果except没有指定错误名称,即:

1 except:
2     #处理除了上述提到的以外的异常和错误

  对于每个try语句,至少有一个相关联的except从句;

  如果某个错误或异常没有被处理,默认的 Python 处理器就会被调用。它会终止 程序的运行,并且打印一个消息;

  最后一个 except 子句可以省略异常名称,以作为通配符使用。你需要慎用此法,因为它会轻易隐藏一个实际的程序错误!!!

可以使用这种方法打印一条错误信息,然后重新抛出异常(允许调用者处理这个异常):

import sys

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

引发异常

  使用raise语句来主动引发异常,需要指明1.异常的名称、2.伴随异常触发的异常对象(描述信息)。

  可以引发的错误或异常应该分别是一个 Error 或 Exception 类的直接或间接导出类。

  raise的基本语法格式为:

raise [exceptionName [(reason)]]
 注意exceptionName和(reason)都是可选的。每次执行 raise 语句,都只能引发一次执行的异常。


 1、如果不带任何参数,单独一个raise,即
raise#该语句引发当前上下文中捕获的异常

  2、指明异常的名称

raise exceptionName #raise 后带一个异常类名称,表示引发执行类型的异常。

  3、指明异常的名称、伴随信息

raise exceptionName("除数不能为零")#引发特定类型异常的同时,附加异常描述信息
raise ShortInputException(len(text),3) 

用户自定义异常

  显然自己定义的异常类需要直接或者间接继承自Exception类。

#1.用户自定义异常类型
class TooLongExceptin(Exception):
    "this is user's Exception for check the length of name "
    def __init__(self,leng):
        self.leng = leng
    def __str__(self):
        print("姓名长度是"+str(self.leng)+",超过长度了")
 
#2.手动抛出用户自定义类型异常
def name_Test():
        name = input("enter your naem:")
        if len(name)>4:
            raise TooLongExceptin(len(name))  #抛出异常很简单,使用raise即可,但是没有处理,即捕捉
        else :
            print(name)
 
#调用函数,执行
name_Test()

运行结果:

Traceback (most recent call last):
  File "d:PiaYieVScodepython学习笔记hello.py", line 49, in <module>
    name_Test()
  File "d:PiaYieVScodepython学习笔记hello.py", line 44, in name_Test
    raise TooLongExceptin(len(name))  #抛出异常很简单,使用raise即可,但是没有处理,即捕捉        
__main__.TooLongExceptin姓名长度是6,超过长度了
: <exception str() failed>

  值得一提的是,主动地引发异常,我们的目的并不是让自己的程序挂机,raise语句引发异常常使用try...excep语句来捕获并进行处理,使得程序更加优雅。

例如:

1 try:
2     a = input("输入一个数:")
3     #判断用户输入的是否为数字
4     if(not a.isdigit()):
5         raise ValueError("a 必须是数字")
6 except ValueError as e:
7     print("引发异常:",repr(e))

运行结果:

输入一个数:l
引发异常: ValueError('a 必须是数字')

try...finally语句

 上面已经提到,finally是可选的,如果存在该语句块,无论是否有异常发生,均会执行该语句块。

 1 import time
 2 
 3 try: 
 4     f = open('poem.txt')
 5     while True:     # our usual file-reading idiom
 6         line = f.readline()
 7         if len(line) == 0:
 8             break
 9         print(line, end = '')
10         time.sleep(2) # To make sure it runs for a while
11 except KeyboardInterrupt:
12     print('!! You cancelled the reading from the file.')
13 finally:
14     f.close()
15     print('(Cleanig up: closed the file)')
16    

运行结果:

123
546
79a
!! You cancelled the reading from the file.
(Cleanig up: closed the file)
D:PiaYieVScodepython学习笔记>

读文件时,每打印一行停顿两秒钟,可以让程序运行的更慢一些,按Ctrl+C中断阅读便发生KeyboardInterrupt异常并且被捕获。

  

我们习惯在 try 块中获得资源,随后又在 finally 块中释放资源。还有一种with...as语句也能完成这样的功能。

with...as语句

1 with open("poem.txt") as f: 
2     for line in f: 
3         print(line,end='')

输出:

123
546
79a
sad

dsad
asdsasdasda

sdasd
asd
D:PiaYieVScodepython学习笔记> 

  with 语句使用 open 函数 —— 用 with open 就能使得在结束的时候自动关闭文件。这是因为with 语句使用了一种协议。获得了 open 语句返回的对象the_obj,在启动代码块之前,在后台总会调用 the_obj.__enter__ 函数,在代码块结束后又 会调用 the_obj.__exit__ 函数。

  显然这种自动的方法可以避免使用显示的try...finally语句。

原文地址:https://www.cnblogs.com/PiaYie/p/13233369.html