python异常处理方法总结

1 异常类型

1.1 Python内置异常

Python的异常处理能力是很强大的,它有很多内置异常,可向用户准确反馈出错信息。在Python中,异常也是对象,可对它进行操作。BaseException是所有内置异常的基类,但用户定义的类并不直接继承BaseException,所有的异常类都是从Exception继承,且都在exceptions模块中定义。Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。

内置异常类的层次结构如下:


 
 
  1. BaseException # 所有异常的基类
  2. +-- SystemExit # 解释器请求退出
  3. +-- KeyboardInterrupt # 用户中断执行(通常是输入^C)
  4. +-- GeneratorExit # 生成器(generator)发生异常来通知退出
  5. +-- Exception # 常规异常的基类
  6. +-- StopIteration # 迭代器没有更多的值
  7. +-- StopAsyncIteration # 必须通过异步迭代器对象的__anext__()方法引发以停止迭代
  8. +-- ArithmeticError # 各种算术错误引发的内置异常的基类
  9. | +-- FloatingPointError # 浮点计算错误
  10. | +-- OverflowError # 数值运算结果太大无法表示
  11. | +-- ZeroDivisionError # 除(或取模)零 (所有数据类型)
  12. +-- AssertionError # 当assert语句失败时引发
  13. +-- AttributeError # 属性引用或赋值失败
  14. +-- BufferError # 无法执行与缓冲区相关的操作时引发
  15. +-- EOFError # 当input()函数在没有读取任何数据的情况下达到文件结束条件(EOF)时引发
  16. +-- ImportError # 导入模块/对象失败
  17. | +-- ModuleNotFoundError # 无法找到模块或在在sys.modules中找到None
  18. +-- LookupError # 映射或序列上使用的键或索引无效时引发的异常的基类
  19. | +-- IndexError # 序列中没有此索引(index)
  20. | +-- KeyError # 映射中没有这个键
  21. +-- MemoryError # 内存溢出错误(对于Python 解释器不是致命的)
  22. +-- NameError # 未声明/初始化对象 (没有属性)
  23. | +-- UnboundLocalError # 访问未初始化的本地变量
  24. +-- OSError # 操作系统错误,EnvironmentError,IOError,WindowsError,socket.error,select.error和mmap.error已合并到OSError中,构造函数可能返回子类
  25. | +-- BlockingIOError # 操作将阻塞对象(e.g. socket)设置为非阻塞操作
  26. | +-- ChildProcessError # 在子进程上的操作失败
  27. | +-- ConnectionError # 与连接相关的异常的基类
  28. | | +-- BrokenPipeError # 另一端关闭时尝试写入管道或试图在已关闭写入的套接字上写入
  29. | | +-- ConnectionAbortedError # 连接尝试被对等方中止
  30. | | +-- ConnectionRefusedError # 连接尝试被对等方拒绝
  31. | | +-- ConnectionResetError # 连接由对等方重置
  32. | +-- FileExistsError # 创建已存在的文件或目录
  33. | +-- FileNotFoundError # 请求不存在的文件或目录
  34. | +-- InterruptedError # 系统调用被输入信号中断
  35. | +-- IsADirectoryError # 在目录上请求文件操作(例如 os.remove())
  36. | +-- NotADirectoryError # 在不是目录的事物上请求目录操作(例如 os.listdir())
  37. | +-- PermissionError # 尝试在没有足够访问权限的情况下运行操作
  38. | +-- ProcessLookupError # 给定进程不存在
  39. | +-- TimeoutError # 系统函数在系统级别超时
  40. +-- ReferenceError # weakref.proxy()函数创建的弱引用试图访问已经垃圾回收了的对象
  41. +-- RuntimeError # 在检测到不属于任何其他类别的错误时触发
  42. | +-- NotImplementedError # 在用户定义的基类中,抽象方法要求派生类重写该方法或者正在开发的类指示仍然需要添加实际实现
  43. | +-- RecursionError # 解释器检测到超出最大递归深度
  44. +-- SyntaxError # Python 语法错误
  45. | +-- IndentationError # 缩进错误
  46. | +-- TabError # Tab和空格混用
  47. +-- SystemError # 解释器发现内部错误
  48. +-- TypeError # 操作或函数应用于不适当类型的对象
  49. +-- ValueError # 操作或函数接收到具有正确类型但值不合适的参数
  50. | +-- UnicodeError # 发生与Unicode相关的编码或解码错误
  51. | +-- UnicodeDecodeError # Unicode解码错误
  52. | +-- UnicodeEncodeError # Unicode编码错误
  53. | +-- UnicodeTranslateError # Unicode转码错误
  54. +-- Warning # 警告的基类
  55. +-- DeprecationWarning # 有关已弃用功能的警告的基类
  56. +-- PendingDeprecationWarning # 有关不推荐使用功能的警告的基类
  57. +-- RuntimeWarning # 有关可疑的运行时行为的警告的基类
  58. +-- SyntaxWarning # 关于可疑语法警告的基类
  59. +-- UserWarning # 用户代码生成警告的基类
  60. +-- FutureWarning # 有关已弃用功能的警告的基类
  61. +-- ImportWarning # 关于模块导入时可能出错的警告的基类
  62. +-- UnicodeWarning # 与Unicode相关的警告的基类
  63. +-- BytesWarning # 与bytes和bytearray相关的警告的基类
  64. +-- ResourceWarning # 与资源使用相关的警告的基类。被默认警告过滤器忽略。

详细说明请参考:https://docs.python.org/3/library/exceptions.html#base-classes

1.2 requests模块的相关异常

在做爬虫时,requests是一个十分好用的模块,所以我们在这里专门探讨一下requests模块相关的异常。

要调用requests模块的内置异常,只要“from requests.exceptions import xxx”就可以了,比如:

from requests.exceptions import ConnectionError, ReadTimeout
 
 

或者直接这样也是可以的:

from requests import ConnectionError, ReadTimeout
 
 

requests模块内置异常类的层次结构如下:


 
 
  1. IOError
  2. +-- RequestException # 处理不确定的异常请求
  3. +-- HTTPError # HTTP错误
  4. +-- ConnectionError # 连接错误
  5. | +-- ProxyError # 代理错误
  6. | +-- SSLError # SSL错误
  7. | +-- ConnectTimeout(+-- Timeout) # (双重继承,下同)尝试连接到远程服务器时请求超时,产生此错误的请求可以安全地重试。
  8. +-- Timeout # 请求超时
  9. | +-- ReadTimeout # 服务器未在指定的时间内发送任何数据
  10. +-- URLRequired # 发出请求需要有效的URL
  11. +-- TooManyRedirects # 重定向太多
  12. +-- MissingSchema(+-- ValueError) # 缺少URL架构(例如http或https)
  13. +-- InvalidSchema(+-- ValueError) # 无效的架构,有效架构请参见defaults.py
  14. +-- InvalidURL(+-- ValueError) # 无效的URL
  15. | +-- InvalidProxyURL # 无效的代理URL
  16. +-- InvalidHeader(+-- ValueError) # 无效的Header
  17. +-- ChunkedEncodingError # 服务器声明了chunked编码但发送了一个无效的chunk
  18. +-- ContentDecodingError(+-- BaseHTTPError) # 无法解码响应内容
  19. +-- StreamConsumedError(+-- TypeError) # 此响应的内容已被使用
  20. +-- RetryError # 自定义重试逻辑失败
  21. +-- UnrewindableBodyError # 尝试倒回正文时,请求遇到错误
  22. +-- FileModeWarning(+-- DeprecationWarning) # 文件以文本模式打开,但Requests确定其二进制长度
  23. +-- RequestsDependencyWarning # 导入的依赖项与预期的版本范围不匹配
  24. Warning
  25. +-- RequestsWarning # 请求的基本警告

详细说明及源码请参考:http://www.python-requests.org/en/master/_modules/requests/exceptions/#RequestException

下面是一个简单的小例子,python内置了一个ConnectionError异常,这里可以不用再从requests模块import了:


 
 
  1. import requests
  2. from requests import ReadTimeout
  3. def get_page(url):
  4. try:
  5. response = requests.get(url, timeout= 1)
  6. if response.status_code == 200:
  7. return response.text
  8. else:
  9. print( 'Get Page Failed', response.status_code)
  10. return None
  11. except (ConnectionError, ReadTimeout):
  12. print( 'Crawling Failed', url)
  13. return None
  14. def main():
  15. url = 'https://www.baidu.com'
  16. print(get_page(url))
  17. if __name__ == '__main__':
  18. main()

1.3 用户自定义异常

此外,你也可以通过创建一个新的异常类拥有自己的异常,异常应该是通过直接或间接的方式继承自Exception类。下面创建了一个MyError类,基类为Exception,用于在异常触发时输出更多的信息。

  在try语句块中,抛出用户自定义的异常后执行except部分,变量 e 是用于创建MyError类的实例。


 
 
  1. class MyError(Exception):
  2. def __init__(self, msg):
  3. self.msg = msg
  4. def __str__(self):
  5. return self.msg
  6. try:
  7. raise MyError( '类型错误')
  8. except MyError as e:
  9. print( 'My exception occurred', e.msg)

2. 异常捕获

当发生异常时,我们就需要对异常进行捕获,然后进行相应的处理。python的异常捕获常用try...except...结构,把可能发生错误的语句放在try模块里,用except来处理异常,每一个try,都必须至少对应一个except。此外,与python异常相关的关键字主要有:

关键字关键字说明
try/except捕获异常并处理
pass忽略异常
as定义异常实例(except MyError as e)
else如果try中的语句没有引发异常,则执行else中的语句
finally无论是否出现异常,都执行的代码
raise    抛出/引发异常

异常捕获有很多方式,下面分别进行讨论。

2.1 捕获所有异常

包括键盘中断和程序退出请求(用sys.exit()就无法退出程序了,因为异常被捕获了),因此慎用。


 
 
  1. try:
  2. <语句>
  3. except:
  4. print( '异常说明')

 

2.2 捕获指定异常


 
 
  1. try:
  2. <语句>
  3. except <异常名>:
  4. print( '异常说明')

万能异常:


 
 
  1. try:
  2. <语句>
  3. except Exception:
  4. print( '异常说明')

一个例子:


 
 
  1. try:
  2. f = open( "file-not-exists", "r")
  3. except IOError as e:
  4. print( "open exception: %s: %s" %(e.errno, e.strerror))

2.3 捕获多个异常

捕获多个异常有两种方式,第一种是一个except同时处理多个异常,不区分优先级:


 
 
  1. try:
  2. <语句>
  3. except (<异常名 1>, <异常名 2>, ...):
  4. print( '异常说明')

第二种是区分优先级的:


 
 
  1. try:
  2. <语句>
  3. except <异常名 1>:
  4. print( '异常说明1')
  5. except <异常名 2>:
  6. print( '异常说明2')
  7. except <异常名 3>:
  8. print( '异常说明3')

该种异常处理语法的规则是:

  • 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
  • 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
  • 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
  • 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。

2.4 异常中的else

如果判断完没有某些异常之后还想做其他事,就可以使用下面这样的else语句。


 
 
  1. try:
  2. <语句>
  3. except <异常名 1>:
  4. print( '异常说明1')
  5. except <异常名 2>:
  6. print( '异常说明2')
  7. else:
  8. <语句> # try语句中没有异常则执行此段代码

2.5 异常中的finally

try...finally...语句无论是否发生异常都将会执行最后的代码。


 
 
  1. try:
  2. <语句>
  3. finally:
  4. <语句>

看一个示例:


 
 
  1. str1 = 'hello world'
  2. try:
  3. int(str1)
  4. except IndexError as e:
  5. print(e)
  6. except KeyError as e:
  7. print(e)
  8. except ValueError as e:
  9. print(e)
  10. else:
  11. print( 'try内没有异常')
  12. finally:
  13. print( '无论异常与否,都会执行我')

2.6 raise主动触发异常

可以使用raise语句自己触发异常,raise语法格式如下:

raise [Exception [, args [, traceback]]]
 
 

语句中Exception是异常的类型(例如ValueError),参数是一个异常参数值。该参数是可选的,如果不提供,异常的参数是"None"。最后一个参数是跟踪异常对象,也是可选的(在实践中很少使用)。

看一个例子:


 
 
  1. def not_zero(num):
  2. try:
  3. if num == 0:
  4. raise ValueError( '参数错误')
  5. return num
  6. except Exception as e:
  7. print(e)
  8. not_zero( 0)

2.7 采用traceback模块查看异常

发生异常时,Python能“记住”引发的异常以及程序的当前状态。Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息。记住,异常可能在一系列嵌套较深的函数调用中引发。程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名。一旦异常被引发,Python会搜索一个相应的异常处理程序。如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止。这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(StackUnwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。

格式如下:


 
 
  1. try:
  2. block
  3. except:
  4. traceback.print_exc()

举个栗子:


 
 
  1. try:
  2. 1/ 0
  3. except Exception as e:
  4. print(e)

如果我们这样写的话,程序只会报“division by zero”错误,但是我们并不知道是在哪个文件哪个函数哪一行出的错。

下面使用traceback模块,官方参考文档:https://docs.python.org/2/library/traceback.html


 
 
  1. import traceback
  2. try:
  3. 1/ 0
  4. except Exception as e:
  5. traceback.print_exc()

这样就会帮我们追溯到出错点:


 
 
  1. Traceback (most recent call last):
  2. File "E:/PycharmProjects/ProxyPool-master/proxypool/test.py", line 4, in <module>
  3. 1/ 0
  4. ZeroDivisionError: division by zero

另外,traceback.print_exc()跟traceback.format_exc()有什么区别呢?

区别就是,format_exc()返回字符串,print_exc()则直接给打印出来。即traceback.print_exc()与print(traceback.format_exc())效果是一样的。print_exc()还可以接受file参数直接写入到一个文件。比如可以像下面这样把相关信息写入到tb.txt文件去。

traceback.print_exc(file=open('tb.txt','w+'))
 
 

参考博文:

except as e中的‘e’的作用总结

python使用traceback获取详细的异常信息

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python异常处理机制允许程序员在程序捕获和处理异常。异常是在程序运行时发生的特殊情况,例如访问列表越界、除以 0 等。异常处理可以帮助程序员避免程序意外崩溃,并且可以提供有意义的错误信息给用户。 Python 使用 try 和 except 关键字来处理异常。使用 try 块来指定需要被检查的代码,使用 except 块来处理异常。例如: ``` try: # 代码块 except ExceptionType: # 异常处理代码块 ``` 如果在 try 块发生异常,那么程序会跳转到 except 块并执行 except 块代码。如果没有发生异常,则 except 块不会执行。你可以使用多个 except 块来处理不同类型的异常。 Python 还提供了一个可选的 else 块,它在 try 块没有发生异常时执行。你还可以使用 finally 块来在 try、except 和 else 块之后执行代码。 例如: ``` try: # 代码块 except ExceptionType: # 异常处理代码块 else: # 没有异常时执行的代码块 finally: # 无论是否发生异常都会执行的代码块 ``` ### 回答2: Python异常处理机制是一种用于处理程序运行过程可能出现的错误或异常情况的机制。在程序执行过程,如果出现了异常,则可以通过异常处理机制捕获并处理这些异常,以避免程序崩溃或产生不可预料的结果。 Python 异常处理机制主要包括两个关键字:try 和 except。通过使用 try 关键字包围可能出现异常的代码块,程序会尝试执行这部分代码,如果没有发生异常,则正常执行后续的代码;而如果发生了异常,则会跳出当前代码块,并根据异常类型执行对应的 except 代码块。 在 except 代码,可以指定捕获的异常类型,以及相应的处理逻辑。当发生异常时,Python 会按照代码 except 代码块的顺序进行匹配,如果找到与异常类型相符合的 except 代码块,则执行该代码的逻辑;如果找不到匹配的 except 代码块,则异常将会被抛出并终止程序的执行。 除了基本的异常处理方式外,Python 还提供了一些高级的异常处理方式。其,可以使用 else 关键字在没有发生异常时执行额外的代码;使用 finally 关键字在无论是否发生异常时都会执行的代码;还可以使用 raise 关键字手动触发异常。 异常处理的好处在于它能够使程序更加健壮,能够在出现异常时及时捕获并处理,有效避免程序的崩溃。同时,异常处理还可以提高代码的可读性和维护性,使得代码更加清晰明了。 总结来说,Python异常处理机制通过 try 和 except 关键字,可以捕获并处理程序出现的异常,保证程序的正常执行,提高代码的健壮性和可维护性。 ### 回答3: Python异常处理机制是一种用于编写稳健程序的重要工具。在Python,异常是指程序运行过程可能出现的错误或异常情况。当程序出现异常时,如果不进行处理,程序将崩溃并输出错误信息。为了优雅地处理异常,Python提供了一套异常处理机制。 在Python,使用try-except语句块来捕捉和处理异常。try块包含可能引发异常的代码,而except块则用于处理异常。当try块代码执行时,如果出现异常,程序会跳转到与其匹配的except块,并执行相应的处理逻辑。可以使用多个except块来处理不同类型的异常,也可以使用一个except块来捕获多个异常类型。 在except块,可以编写处理异常的代码逻辑。这些代码将在异常出现时执行,可以用于记录日志、输出错误信息等。如果except块代码成功执行,程序将继续执行后续代码。如果except块代码出现错误,那么该错误将继续向上级代码抛出,直到找到匹配的异常处理块或程序结束。 除了try-except语句块,Python还提供了finally语句块。finally语句块代码块始终会被执行,无论是否出现异常。通常情况下,finally语句块用于执行清理操作,如关闭文件、释放资源等。 在使用异常处理机制时,应该尽可能具体地捕获异常类型,而不是简单地使用通用的异常处理语句。这样可以更好地定位和处理异常,提高程序的健壮性和可靠性。 总之,Python异常处理机制是一种用于处理和优雅处理程序出现的异常的重要工具。合理使用异常处理机制可以提高程序的稳定性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值