Python 关于捕获任何异常

Python 关于捕获任何异常,python,exception-handling,Python,Exception Handling,除了捕获所有异常的块之外,如何编写一个try/ try: whatever() except: # this will catch any exception or error 值得一提的是,这不是正确的Python编码。这还将捕获许多您可能不想捕获的错误。您可以,但可能不应该: try: do_something() except: print "Caught it!" 但是,这也会捕获异常,例如键盘中断,您通常不希望这样,是吗?除非立即重新引发异常-请参见

除了捕获所有异常的块之外,如何编写一个
try
/

try:
    whatever()
except:
    # this will catch any exception or error

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

您可以,但可能不应该:

try:
    do_something()
except:
    print "Caught it!"
但是,这也会捕获异常,例如
键盘中断
,您通常不希望这样,是吗?除非立即重新引发异常-请参见以下示例:


除了一个简单的
except:
子句(正如其他人所说,您不应该使用该子句),您只需捕获:

你通常只考虑在代码的最外层进行这样的操作,例如,在终止之前,你想处理任何其他异常的异常。


与裸
Exception
相比,
Exception
的优势在于它不会捕捉到一些异常,最明显的是
键盘中断
系统退出
:如果捕捉到并吞下了这些异常,那么任何人都很难退出脚本。

非常简单的例子,类似于此处发现的:

如果您试图捕获所有异常,那么将所有代码放在“try:”语句中,而不是执行可能引发异常的操作的“print”

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

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

2) 无论是否引发异常,在执行try语句后直接调用Finally

3) “抛出异常!”或“一切看起来都很好!”取决于是否抛出异常


希望这有帮助

您可以这样做来处理一般异常

try:
    a = 2/0
except Exception as e:
    print e.__doc__
    print e.message

要捕获所有可能的异常,请捕获
BaseException
。它位于异常层次结构的顶部:

Python 3:

Python 2.7:


但正如其他人所提到的,您通常不需要它,只需要在特定情况下使用。

我刚刚发现了在Python 2.7中测试异常名称的小技巧。有时我会在代码中处理特定的异常,因此我需要进行测试,以查看该名称是否在已处理异常的列表中

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

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

方法1

这是一种简单的方法,但不推荐使用,因为您不知道哪行代码实际引发了异常:

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

bad_method()
方法2

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

  • 代码的行号
  • 文件名
  • 以更详细的方式显示实际错误
唯一的缺点是tracback需要导入

import traceback

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

bad_method()

可能的解决方法:你真的应该打印到stderr。我非常非常强烈地不同意“不应该”的说法。你应该谨慎地做。有时,当您处理第三方库(有时是动态加载的!!)时,异常会变得非常疯狂,跟踪它们可能是一项非常痛苦的任务,如果您只错过了一个,那么您的系统中就有一个非常非常痛苦的bug。也就是说,尽可能多地跟踪并适当地处理它们,然后为您错过的内容提供一个全面的备份是很好的。我发现同样奇怪的是,在duck类型语言中,您不声明实例变量,它突然非常担心没有键入所有的异常。隐马尔可夫模型!仍然缺少
,例外除外:
。我也有同样的想法,但它们是一个缺点,假设它们是两个错误,当一次被捕获时,除了打印之外,您将退出try块,并且您永远不会知道第二个错误……对于任何想知道的人来说,与我的预期完全相反,至少在Python2.x中,@JosephGarvin,这是不正确的,也就是说,这将不会捕获非子类
异常的“非异常”。请注意,不可能将
int
作为异常引发,并且尝试这样做会引发
TypeError
异常,在这种情况下,这就是所包含的
exception
子句所捕获的异常。另一方面,一个旧式的类可以被提升并被限定为一个“非异常”,而不是子类
exception
——这将被一个裸露的
exception
子句捕获,但不会被
exception
子句捕获。@JosephGarvin查看这篇博文:我在这篇博文中支持@Yoel,您的测试只是掩盖了
类型错误
@CharlieParker如果这是您想要的,那么捕获它们并没有什么错,但您基本上没有。调用
sys.exit()
通常意味着您希望应用程序终止,但如果捕获到SystemExit,则不会终止。同样,如果在正在运行的脚本上点击control-C(windows上的Ctrl-break),您希望程序停止,而不是捕获错误并继续运行。但是,如果您想在存在之前进行清理,您可以捕获其中一个/两个。在大多数情况下,如果您试图捕获任何异常,那么您可能在执行smth时出错。我的意思是,你可以简单地在代码中拼错一些东西,你甚至不知道。捕获特定的异常是一个很好的实践。更准确地说,捕获所有可能的异常只是一个问题,如果它们是静默捕获的。除了捕获的错误消息被打印到
sys.stderr
并可能被记录之外,很难想象这种方法还适用于其他什么地方。这是一个非常有效且常见的异常。您是否尝试过:
try:whatever(),但异常为e:exp\u capture()
?相关:这是否回答了您的问题?这可能不会捕获所有异常,因为所有异常的基类都是BaseException,并且我遇到了不在Exception类系列中的生产代码。请参阅
try:
    something()
except BaseException as error:
    print('An exception occurred: {}'.format(error))
try:
    raise IndexError #as test error
except Exception as e:
    excepName = type(e).__name__ # returns the name of the exception
def bad_method():
    try:
        sqrt = 0**-1
    except Exception as e:
        print(e)

bad_method()
import traceback

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

bad_method()