iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >如何动态捕获Python异常
  • 308
分享到

如何动态捕获Python异常

2023-06-17 08:06:16 308人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

如何动态捕获python异常,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。在讨论动态捕获异常时让我大吃一惊的是,可以让我找到隐藏的Bug和乐趣。有问题的代码下面

如何动态捕获python异常,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

在讨论动态捕获异常时让我大吃一惊的是,可以让我找到隐藏的Bug和乐趣。

有问题的代码

下面的代码来自一个产品中看起来是好的抽象代码 - slightly(!) .这是调用一些统计数据的函数,然后进行处理 . 首先是用Socket连接获取一个值,可能发生了socket错误.由于统计数据在系统中不是至关重要的,我们只是记一下日志错误并继续往下走.

(请注意,这篇文章我使用doctest测试的 - 这代表代码可以运行!)

>>> def get_stats():  ...     pass ...  >>> def do_something_with_stats(stats):  ...     pass ...  >>> try:  ...     stats = get_stats()  ... except socket.error:  ...     logging.warning("Can't get statistics")  ... else:  ...     do_something_with_stats(stats)

查找

我们测试时并没有发现不妥, 但实际上我们注意到静态分析报告显示一个问题:

$ flake8 filename.py  filename.py:351:1: F821 undefined name 'socket' filename.py:352:1: F821 undefined name 'logging'

显然是我们没测试,这个问题是代码中我们没有引用socket 和 logging 两个模块.使我感到惊奇的是,这并没有预先抛出NameError错,我以为它会查找这些异常语句中的一些名词,如它需要捕捉这些异常,它需要知道些什么呢!

事实证明并非如此,异常语句的查找是延迟完成的,只是评估时抛出异常. 不只是名称延迟查找,也可以定制显示声明异常做为'参数(argument)'.

这可能是好事,坏事,或者是令人厌恶的.

好事(上段中提到的)

异常参数可以以任意形式数值传递. 这样就允许了异常的动态参数被捕获.

>>> def do_something():  ...    blob  ...  >>> def attempt(action, ignore_spec):  ...     try:  ...         action()  ...     except ignore_spec:  ...         pass ...  >>> attempt(do_something, ignore_spec=(NameError, TypeError))  >>> attempt(do_something, ignore_spec=TypeError)  Traceback (most recent call last):    ...  NameError: global name 'blob' is not defined

坏事(上段中提到的)

这种明显的弊端就是异常参数中的错误通常只有在异常触发之后才会被注意到,不过为时已晚.当用异常去捕获不常见的事件时(例如:以写方式打开文件失败), 除非做个一个特定的测试用例,否则只有当一个异常(或者任何异常)被触发的时候才会知道, 届时记录下来并且查看是否有匹配的异常, 并且抛出它自己的错误异常 - 这是一个NameError通常所做的事情.

>>> def do_something():  ...     return 1, 2 ...  >>> try:  ...     a, b = do_something()  ... except ValuError:  # oops - someone can't type  ...     print("Oops")  ... else:  ...     print("OK!")   # we are 'ok' until do_something returns a triple...  OK!

令人讨厌的(上段中提到的)

>>> try:  ...    TypeError = ZeroDivisionError  # now why would we do this...?!  ...    1 / 0 ... except TypeError:  ...    print("Caught!")  ... else:  ...    print("ok")  ...  Caught!

不仅仅是异常参数通过名称查找, - 其它的表达式也是这样工作的:

>>> try:  ...     1 / 0 ... except eval(''.join('Zero Division Error'.split())):  ...     print("Caught!")  ... else:  ...     print("ok")  ...  Caught!

异常参数不仅仅只能在运行时确定,它甚至可以使用在生命周期内的异常的信息. 以下是一个比较费解的方式来捕捉抛出的异常 - 但也只能如此了:

>>> import sys  >>> def current_exc_type():  ...     return sys.exc_info()[0]  ...  >>> try:  ...     blob  ... except current_exc_type():  ...     print ("Got you!")  ...  Got you!

很明显这才是我们真正要寻找的当我们写异常处理程序时, 我们应该首先想到的就是这种

(字节)代码

为了确认它是如何在异常处理工作中出现的,我在一个异常的例子中运行 dis.dis(). (注意 这里的分解是在Python2.7 下 - 不同的字节码是Python 3.3下产生的,但这基本上是类似的):

>>> import dis  >>> def x():  ...     try:  ...         pass ...     except Blobbity:  ...         print("bad")  ...     else:  ...         print("good")  ...  >>> dis.dis(x)  # doctest: +NORMALIZE_WHITESPACE    2           0 SETUP_EXCEPT             4 (to 7)  <BLANKLINE>    3           3 POP_BLOCK                4 JUMP_FORWARD            22 (to 29)  <BLANKLINE>    4     >>    7 DUP_TOP                8 LOAD_GLOBAL              0 (Blobbity)               11 COMPARE_OP              10 (exception match)               14 POP_JUMP_IF_FALSE       28              17 POP_TOP               18 POP_TOP               19 POP_TOP  <BLANKLINE>    5          20 LOAD_CONST               1 ('bad')               23 PRINT_ITEM               24 PRINT_NEWLINE               25 JUMP_FORWARD             6 (to 34)          >>   28 END_FINALLY  <BLANKLINE>    7     >>   29 LOAD_CONST               2 ('good')               32 PRINT_ITEM               33 PRINT_NEWLINE          >>   34 LOAD_CONST               0 (None)               37 RETURN_VALUE

这显示出了我原来预期的问题(issue). 异常处理"看起来"完全是按照Python内部机制在运行. 这一步完全没有必要知道关于后续的异常“捕获”语句, 并且如果没有异常抛出它们将被完全忽略了.SETUP_EXCEPT并不关心发生了什么, 仅仅是如果发生了异常, ***个处理程序应该被评估,然后第二个,以此类推.

每个处理程序都有两部分组成: 获得一个异常的规则, 和刚刚抛出的异常进行对比. 一切都是延迟的, 一切看起来正如对你的逐行的代码的预期一样, 从解释器的角度来考虑. 没有任何聪明的事情发生了,只是突然使得它看起来非常聪明.

总结

虽然这种动态的异常参数让我大吃一惊, 但是这当中包含很多有趣的应用. 当然去实现它们当中的许多或许是个馊主意,呵呵

有时并不能总是凭直觉来确认有多少Python特性的支持 - 例如 在类作用域内 表达式和声明都是被显式接受的, (而不是函数, 方法, 全局作用域),但是并不是所有的都是如此灵活的. 虽然(我认为)那将是十分美好的, 表达式被禁止应用于装饰器 - 以下是Python语法错误:

@(lambda fn: fn)  def x():     pass

这个是尝试动态异常参数通过给定类型传递给***个异常的例子, 静静的忍受重复的异常:

>>> class Pushover(object):  ...     exc_spec = set()  ...  ...     def attempt(self, action):  ...         try:  ...             return action()  ...         except tuple(self.exc_spec):  ...             pass ...         except BaseException as e:  ...             self.exc_spec.add(e.__class__)  ...             raise ...  >>> pushover = Pushover()  >>>  >>> for _ in range(4):  ...     try:  ...         pushover.attempt(lambda: 1 / 0)  ...     except:  ...         print ("Boo")  ...     else:  ...         print ("Yay!")  Boo  Yay!  Yay!  Yay!

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网Python频道,感谢您对编程网的支持。

--结束END--

本文标题: 如何动态捕获Python异常

本文链接: https://www.lsjlt.com/news/288014.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何动态捕获Python异常
    如何动态捕获Python异常,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。在讨论动态捕获异常时让我大吃一惊的是,可以让我找到隐藏的Bug和乐趣。有问题的代码下面...
    99+
    2023-06-17
  • Python编程中如何捕获警告ps不是捕获异常
    目录1.警告不是异常2.警告能捕获吗3.捕获警告方法一4.捕获警告方法二5.捕获警告方法三1. 警告不是异常 你是不是经常在使用一些系统库或者第三方模块的时候,会出现一些既不是异常也...
    99+
    2022-11-12
  • 详解python的异常捕获
    目录①捕捉一个异常②捕捉多个异常③Exception捕捉所有异常④raise主动触发异常⑤try…except…else…finally逻辑...
    99+
    2022-11-13
  • Python多层异常的捕获
    参考: 1、https://mozillazg.github.io/2016/08/python-the-right-way-to-catch-exception-then-reraise-another-exception.h...
    99+
    2023-01-31
    多层 异常 Python
  • python异常捕获详解流程
    1 捕捉一个异常 捕捉一个异常 以用0作为除数会得到ZeroDivisionError异常为例, print(1/0) 为例程序的持续执行,不因该异常而中止, 遂对该异常进...
    99+
    2022-11-13
  • python try-except怎么捕获异常
    这篇文章主要介绍“python try-except怎么捕获异常”,在日常操作中,相信很多人在python try-except怎么捕获异常问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python try-...
    99+
    2023-06-30
  • 如何在Java中捕获异常
    今天就跟大家聊聊有关如何在Java中捕获异常,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;2....
    99+
    2023-06-14
  • python中怎么捕获多个异常
    这篇文章给大家介绍python中怎么捕获多个异常,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、规则说明(1)执行try下的句子,如果引起异常,执行过程会跳到第一个except语句。(2)如果首个except中定义的...
    99+
    2023-06-15
  • python中异常捕获方法详解
    在Python中处理异常使用的是try-except代码块,try-except代码块放入让python执行的操作,同时告诉python程序如果发生了异常该怎么办,try-except这个功能其实很多入门书...
    99+
    2022-06-04
    详解 异常 方法
  • python线程捕获不到异常如何解决
    Python线程捕获不到异常的原因是因为线程中的异常默认是不会被抛出到主线程的。 解决这个问题,可以使用try/except语句在线...
    99+
    2023-10-27
    python
  • React如何优雅的捕获异常
    目录前言 ErrorBoundary Error Boundary 之外 try/catch window.onerror , error事件 unhandledrejection ...
    99+
    2022-11-12
  • python捕获异常的方法是什么
    在Python中,可以使用try-except语句来捕获异常。 语法如下: try: # 可能会产生异常的代码块 excep...
    99+
    2023-10-26
    python
  • Python面向对象之异常捕获(一)--
    大部分的异常都继承自Exception这个类(而这个类有继承自BaseException这个类) ValueError TypeError IndexError   下面这个类的作用是:添加偶数到列表中去。 # 添加偶数到列表中...
    99+
    2023-01-31
    面向对象 异常 Python
  • 关于Python的异常捕获和处理
    目录1 | 语法错误2 | 运行时错误3 |其他异常4 | 异常处理try except 语句的执行流程如下:5 | 获取特定异常的有关信息6 |finally语句 程序运...
    99+
    2023-05-17
    Python异常 Python异常捕获 Python异常处理
  • python捕获异常的方法有哪些
    在Python中,有以下几种方法可以捕获异常:1. try-except语句:使用try-except语句块可以捕获异常。在try块...
    99+
    2023-08-08
    python
  • 异常处理:PHP中如何捕获和处理异常?
    异常处理:PHP中如何捕获和处理异常?在PHP开发中,异常处理是非常重要的一环。当程序发生意外情况或错误时,我们需要通过捕获和处理异常来保证程序的正常运行。PHP中提供了一套异常处理的机制,本文将介绍如何在PHP中捕获和处理异常,并提供具体...
    99+
    2023-12-18
    捕获 处理 异常
  • java捕获异常后如何继续执行
    在Java中,可以使用try-catch语句来捕获异常并处理它们。一旦异常被捕获,程序会跳转到catch块中执行相应的代码,然后继续...
    99+
    2023-09-15
    java
  • SqlServer中存储过程如何捕获异常
    这期内容当中小编将会给大家带来有关SqlServer中存储过程如何捕获异常,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。  SqlServer中的存储过程怎么捕获异常  ...
    99+
    2022-10-18
  • python怎样在一行中捕获多个异常
    所属网站分类: python基础 > 异常处理 作者:浮沉 链接:http://www.pythonheidong.com/blog/article/71/ 来源:python黑洞网,专注python资源,python教程,...
    99+
    2023-01-31
    多个 异常 python
  • springboot如何自定义异常并捕获异常返给前端
    小编给大家分享一下springboot如何自定义异常并捕获异常返给前端,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!背景在开发中,如果用try catch的方式,...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作