如何在一行中捕获多个异常?(在“except”块中)

2024-12-09 08:30:00
admin
原创
145
摘要:问题描述:我知道我能做到:try: # do something that may fail except: # do this if ANYTHING goes wrong 我也可以这样做:try: # do something that may fail except IDontL...

问题描述:

我知道我能做到:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

我也可以这样做:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

但是,如果我想在两个不同的异常中做同样的事情,我现在能想到的最好的办法就是这样做:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

有什么办法可以做这样的事情吗(因为在两种例外情况下要采取的行动是say please):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

现在这真的不起作用了,因为它符合以下语法:

try:
    # do something that may fail
except Exception, e:
    # say please

因此,我捕捉这两个不同异常的努力并没有完全成功。

有办法吗?


解决方案 1:

来自Python文档:

except 子句可以将多个异常命名为带括号的元组,例如

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

或者,仅适用于 Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

用逗号将异常与变量分隔在 Python 2.6 和 2.7 中仍然有效,但现在已被弃用并且在 Python 3 中不起作用;现在您应该使用as

解决方案 2:

如何在一行中捕获多个异常(除块外)

这样做:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

由于旧语法使用逗号将错误对象分配给名称,因此需要使用括号。关键字as用于分配。您可以为错误对象使用任何名称,我error个人更喜欢这样。

最佳实践

为了以当前的方式并与 Python 向前兼容,您需要用逗号分隔异常并用括号将它们包裹起来,以区别于之前的语法,该语法通过在要捕获的异常类型后面加上逗号来将异常实例分配给变量名。

以下是一个简单用法的示例:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    sys.exit(0)

我仅指定这些异常以避免隐藏错误,如果遇到错误,我希望得到完整的堆栈跟踪。

此处记录了此内容:https://docs.python.org/tutorial/errors.html

您可以将异常分配给一个变量(e这很常见,但如果您的异常处理很长,或者您的 IDE 只突出显示大于该范围的选择,您可能更喜欢更详细的变量,就像我的一样)。该实例具有 args 属性。以下是一个例子:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    sys.exit(0)

请注意,在 Python 3 中,当块结束err时,对象就会超出范围。except

已弃用

您可能会看到使用逗号分配错误的代码。这种用法是 Python 2.5 及更早版本中唯一可用的格式,现已弃用,如果您希望代码在 Python 3 中向前兼容,则应更新语法以使用新格式:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    sys.exit(0)

如果您在代码库中看到逗号名称分配,并且您使用的是 Python 2.5 或更高版本,请切换到新的方式,以便您的代码在升级时保持兼容。

suppress上下文管理器

可接受的答案实际上至少有 4 行代码:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

可以使用 Python 3.4 中的 suppress 上下文管理器在一行中处理tryexcept、行:pass

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

因此,当您想要pass处理某些例外情况时,请使用suppress

解决方案 3:

来自Python 文档 -> 8.3 处理异常:

一个try语句可以有多个 except 子句,用于指定不同异常的处理程序。最多会执行一个处理程序。处理程序仅处理相应 try 子句中发生的异常,而不会处理同一 try 语句的其他处理程序中发生的异常。一个 except 子句可以将多个异常命名为带括号的元组,例如:

except (RuntimeError, TypeError, NameError):
    pass

请注意,此元组周围的括号是必需的,因为 exceptValueError, e:是现代 Python 中通常使用的语法except ValueError as e:(如下所述)。旧语法仍受支持以实现向后兼容。这意味着except RuntimeError, TypeError不等同于
except (RuntimeError, TypeError):except RuntimeError as
TypeError:等同于不是您想要的。

解决方案 4:

如果频繁使用大量异常,可以预先定义一个元组,这样就不必多次重新输入它们。

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

笔记:

  1. 如果您还需要捕获预定义元组之外的其他异常,则需要定义另一个 except 块。

  2. 如果您无法容忍全局变量,请在 main() 中定义它并将其传递到需要的地方......

解决方案 5:

实现此目的的方法之一是..

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

另一种方法是创建执行except块执行任务的方法并通过您编写的所有except块调用它。

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

我知道第二种方法不是最好的方法,但我只是展示了几种方法。

解决方案 6:

从 Python 3.11 开始,您可以利用except*用于处理多个异常的子句。

PEP-654 引入了一种新的标准异常类型,称为ExceptionGroup,它对应于一组一起传播的异常。ExceptionGroup可以使用新语法来处理except**符号 表示每个子句可以处理多个异常except*


例如,你可以处理多个异常

try:
    raise ExceptionGroup('Example ExceptionGroup', (
        TypeError('Example TypeError'),
        ValueError('Example ValueError'),
        KeyError('Example KeyError'),
        AttributeError('Example AttributeError')
    ))
except* TypeError:
    ...
except* ValueError as e:
    ...
except* (KeyError, AttributeError) as e:
    ...

有关更多详细信息,请参阅PEP-654。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用