关于捕获任何异常

use*_*652 635 python exception-handling

如何编写捕获所有异常的try/ exceptblock?

Dun*_*can 749

除了一个裸except:条款(正如其他人所说,你不应该使用),你可以简单地抓住Exception:

import traceback
import logging

try:
    whatever()
except Exception as e:
    logging.error(traceback.format_exc())
    # Logs the error appropriately. 
Run Code Online (Sandbox Code Playgroud)

您通常只会考虑在代码的最外层执行此操作,例如,您希望在终止之前处理任何其他未捕获的异常.

的优势,except Exception在裸露的except是,有少数例外,它不会赶上,最明显KeyboardInterruptSystemExit:如果你抓住了,吞下这些,那么你可以让任何人都很难离开你的脚本.

  • 对于任何想知道的人来说,完全违背我的期望,这仍然会捕获像int这样的非异常子类,至少在python 2.x中. (6认同)
  • @JosephGarvin,这是不正确的,即这不会捕获不包含"异常"子类的"非异常".请注意,将`int`作为异常引发是不可能的,并且尝试这样做会引发一个`TypeError`异常,在这种情况下,封闭的`除了Exception`子句会被捕获.另一方面,旧式类可以被提升并且被定义为"非例外",它不是子类"异常" - 这个**将被一个简单的`except`子句捕获但是**不是**由"除异常"条款组成. (5认同)
  • @JosephGarvin检查这个博客文章:https://chris-lamb.co.uk/posts/no-one-expects-string-literal-exception我和@Yoel在这个上面,你的测试只是屏蔽了`TypeError` (4认同)
  • @CharlieParker你可以尝试` except BaseException as e: notify_user(e); raise` 会捕获所有异常并执行您需要的任何通知,但我不知道 HPC,所以您可能想问一个新的 SO 问题。 (3认同)
  • @CharlieParker 如果这就是你想要的但你大多不想要的话,抓住它们并没有什么错。调用 sys.exit() 通常意味着您希望应用程序终止,但如果您捕获 SystemExit 它不会终止。同样,如果您在正在运行的脚本上按 Control-C(在 Windows 上按 Ctrl-break),您希望程序停止,而不是捕获错误并继续运行。但是,如果您想在存在之前进行清理,则可以捕获其中一个/两个。 (2认同)

Tim*_*ker 520

你可以,但你可能不应该:

try:
    do_something()
except:
    print "Caught it!"
Run Code Online (Sandbox Code Playgroud)

但是,这也会捕获异常KeyboardInterrupt,你通常不希望这样,是吗?除非您立即重新提出异常 - 请参阅文档中的以下示例:

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

  • 我非常非常不同意这一说法,"不应该." 你应该谨慎地做.有时候你正在处理第三方库(有时是动态加载的!!),这些库已经完全疯狂了,并且跟踪它们都是非常痛苦的任务,如果你只想念一个,你就会非常非常你系统中的巨大痛苦错误.话虽如此,最好尽可能多地追踪并妥善处理它们然后为你错过的那些备份. (36认同)
  • 可能的解决方法:http://effbot.org/zone/stupid-exceptions-keyboardinterrupt.htm (28认同)
  • 我觉得很奇怪的是,在你没有声明实例变量的鸭子打字语言中,它突然非常担心没有输入你的所有异常.哼! (22认同)
  • 你的最后一个陈述不是真的,你需要明确地说`除了Exception:`除了你之外的那个也将捕获BaseException. (12认同)
  • 你真的应该打印到stderr. (7认同)
  • 仍然缺少`except Exception:`。 (7认同)
  • 我们可以确认 ` except Exception as e:` 与 `sys.exc_info()[0]` 的区别吗? (2认同)

vwv*_*dya 96

您可以执行此操作来处理常规异常

try:
    a = 2/0
except Exception as e:
    print e.__doc__
    print e.message
Run Code Online (Sandbox Code Playgroud)

  • 这可能无法捕获所有异常,因为所有异常的基类都是BaseException,并且我遇到了不在Exception类系列中的生产代码.有关详细信息,请参阅https://docs.python.org/3/library/exceptions.html?highlight=BaseException. (7认同)
  • 从技术上讲,它应该捕获所有非系统退出的异常.来自文档@DDay链接:"_ exception_ BaseException:所有内置异常的基类.它不是由用户定义的类直接继承(为此,使用Exception)." 除非您正在使用忽略此代码的代码,或者您需要捕获系统退出异常,否则上述内容应该可以使用. (6认同)
  • 这不能捕获所有异常。 (3认同)
  • 并非所有异常都会有“message”属性。 (2认同)
  • 因为在 Python 3 中 print 是一个函数而不是语句。因此你需要用()来调用它。例如打印(电子消息) (2认同)

git*_*rik 51

为了捕获所有可能的异常,请抓住BaseException.它位于异常层次结构之上:

Python 3:https: //docs.python.org/3.5/library/exceptions.html#exception-hierarchy

Python 2.7:https: //docs.python.org/2.7/library/exceptions.html#exception-hierarchy

try:
    something()
except BaseException as error:
    print('An exception occurred: {}'.format(error))
Run Code Online (Sandbox Code Playgroud)

但正如其他人提到的那样,除非你有充分的理由,否则你通常不会这样做.

  • 在按 Ctrl-C 后希望保存长时间运行的作业的进度是不寻常的吗? (2认同)
  • @BallpointBen,那么你可以抓住`KeyboardInterrupt` (2认同)
  • 注意:像这样使用 `BaseException` 很少是您想要的。您真的想捕获键盘中断和 sys.exit 吗?可能不会!所有用户定义的异常都应该继承自“Exception”。看一下异常类的层次结构。https://dotnettutorials.net/wp-content/uploads/2020/07/word-image-181.png (2认同)

Jos*_*rns 50

很简单的例子,类似于这里找到的一个:

http://docs.python.org/tutorial/errors.html#defining-clean-up-actions

如果你试图捕获所有异常,那么将所有代码放在"try:"语句中,代替'print'执行可能抛出异常的动作."'.

try:
    print "Performing an action which may throw an exception."
except Exception, error:
    print "An exception was thrown!"
    print str(error)
else:
    print "Everything looks great!"
finally:
    print "Finally is called directly after executing the try statement whether an exception is thrown or not."
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,您将按以下顺序查看输出:

1)执行可能引发异常的动作.

2)最后在执行try语句后直接调用是否抛出异常.

3)"抛出异常!" 或者"一切看起来都很棒!" 取决于是否抛出异常.

希望这可以帮助!

  • 除了异常,错误:^SyntaxError:语法无效 (2认同)
  • @Tony try: ` except Exception as error:` -- 如果你运行的是 Python3。 (2认同)

小智 24

我添加了额外的方法,可以通过完整的回溯捕获异常,这可以帮助您更多地理解错误。

Python 3

import traceback

try:
    # your code goes here
except Exception as e:
    print(e)
    traceback.print_exc()
Run Code Online (Sandbox Code Playgroud)


Dan*_*ilo 19

我刚刚发现了这个小技巧,用于测试Python 2.7中的异常名称.有时我在代码中处理了特定的异常,所以我需要一个测试来查看该名称是否在处理的异常列表中.

try:
    raise IndexError #as test error
except Exception as e:
    excepName = type(e).__name__ # returns the name of the exception
Run Code Online (Sandbox Code Playgroud)


gre*_*pit 18

有多种方法可以做到这一点,特别是在Python 3.0及更高版本中

方法1

这是简单的方法,但不建议使用,因为您将不知道确切的代码行实际引发异常:

def bad_method():
    try:
        sqrt = 0**-1
    except Exception as e:
        print(e)

bad_method()
Run Code Online (Sandbox Code Playgroud)

方法2

建议使用此方法,因为它提供了有关每个异常的更多详细信息。这包括:

  • 您代码的行号
  • 文档名称
  • 实际错误更详细

唯一的缺点是需要导入tracback。

import traceback

def bad_method():
    try:
        sqrt = 0**-1
    except Exception:
        print(traceback.print_exc())

bad_method()
Run Code Online (Sandbox Code Playgroud)


Yuv*_*dam 11

try:
    whatever()
except:
    # this will catch any exception or error
Run Code Online (Sandbox Code Playgroud)

值得一提的是,这不是正确的 Python 编码。这也会捕获许多您可能不想捕获的错误。


Hos*_*ein 8

首先,有些异常是您希望它们破坏您的代码(因为当此错误发生时,您的代码无论如何都将无法运行!)以及您希望静默/顺利捕获的异常。尝试区分它们。您可能不想捕获所有异常!

其次,您可以花时间查看流程日志,而不是捕获所有内容。假设您收到了不同/第三方的异常,例如来自 GCP 等云服务提供商的异常。在日志中,您可以找到遇到的异常。然后,你可以这样做:

from google.api_core.exceptions import ServiceUnavailable, RetryError

for i in range(10):
   try:
      print("do something")

   except ValueError:
      print("I know this might happen for now at times! skipping this and continuing with my loop"

   except ServiceUnavailable:
      print("our connection to a service (e.g. logging) of gcp has failed")
      print("initializing the cloud logger again and try continuing ...") 

   except RetryError:
      print("gcp connection retry failed. breaking the loop. try again later!)
      break
Run Code Online (Sandbox Code Playgroud)

对于其余的(可能发生或可能不会发生的错误),如果出现意外异常,我会为代码崩溃留出空间!这样我就可以了解正在发生的事情并通过捕获边缘情况来改进我的代码。

如果您希望它永远不会因某种原因崩溃,例如,如果它是嵌入在您无法轻松访问的远程硬件中的代码,则可以在末尾添加通用异常捕获器:

except Exception as e:
   print(f"something went wrong! - {e}")
Run Code Online (Sandbox Code Playgroud)

您还可以在此处查看 Python 3 异常层次结构。Exception和之间的区别BaseException在于,Exception不会捕获SystemExit, KeyboardInterrupt, 或GeneratorExit


归档时间:

查看次数:

562126 次

最近记录:

6 年,8 月 前