如何编写捕获所有异常的 try
/except
块?
sys.stderr
并可能记录的位置之外,很难想到这种方法还有什么合适的地方。这是一个完全有效且常见的例外。
try: whatever() except Exception as e: exp_capture()
?
除了一个简单的 except:
子句(正如其他人所说你不应该使用它),你可以简单地捕获 Exception
:
import traceback
import logging
try:
whatever()
except Exception as e:
logging.error(traceback.format_exc())
# Logs the error appropriately.
您通常只会考虑在代码的最外层执行此操作,例如,如果您想在终止之前处理任何其他未捕获的异常。
except Exception
相对于纯 except
的优势在于它不会捕获一些异常,最明显的是 KeyboardInterrupt
和 SystemExit
:如果您捕获并吞下了它们,那么您可能会让任何人都难以退出你的脚本。
你可以,但你可能不应该:
try:
do_something()
except:
print("Caught it!")
但是,这也会捕获像 KeyboardInterrupt
这样的异常,而您通常不希望这样,对吗?除非您立即重新引发异常 - 请参阅以下示例 from the docs:
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
except Exception:
。
要捕获所有可能的异常,请捕获 BaseException
。它位于异常层次结构之上:
Python 3:https://docs.python.org/3.9/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))
但正如其他人提到的,您通常不需要这个,仅用于特定情况。
except:
会发现吗?但它并没有给我e
的句柄:(
In Python, all exceptions must be instances of a class that derives from BaseException
,但如果您可以在一般情况下省略它 - 省略它,问题是,关于它的葡萄酒。
KeyboardInterrupt
的 SIGINT
的默认信号处理程序。当然,您可以捕获 KeyboardInterrupt
,但它只是可能提前终止程序的众多信号之一。这些不会产生任何异常,因此您不妨统一处理它们。
BaseException
很少是你想要的。你真的想捕捉键盘中断和 sys.exit 吗?可能不是!所有用户定义的异常都应继承自 Exception
。看看异常类层次结构。 dotnettutorials.net/wp-content/uploads/2020/07/…
您可以这样做来处理一般异常
try:
a = 2/0
except Exception as e:
print e.__doc__
print e.message
message
属性。
非常简单的示例,类似于此处找到的示例:
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."
在上面的示例中,您会按以下顺序看到输出:
1) 执行可能引发异常的操作。
2) finally 在执行 try 语句后直接调用,无论是否抛出异常。
3)“抛出异常!”或“一切看起来都很棒!”取决于是否抛出异常。
希望这可以帮助!
except:
会发现吗?但它并没有给我e
的句柄:(
except Exception as error:
- 如果您正在运行 Python3。
有多种方法可以做到这一点,特别是使用 Python 3.0 及更高版本
方法一
这是一种简单的方法,但不推荐使用,因为您不会确切知道哪一行代码实际上引发了异常:
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()
except:
会发现吗?但它并没有给我e
的句柄:(
traceback.print_exc()
?
我刚刚发现了这个在 Python 2.7 中测试异常名称的小技巧。有时我已经在代码中处理了特定的异常,所以我需要测试以查看该名称是否在已处理异常的列表中。
try:
raise IndexError #as test error
except Exception as e:
excepName = type(e).__name__ # returns the name of the exception
except:
会发现吗?但它并没有给我e
的句柄:(
我正在添加可以通过完整回溯捕获异常的奖励方法,这可以帮助您更多地了解错误。
Python 3
import traceback
try:
# your code goes here
except Exception as e:
print(e)
traceback.print_exc()
try:
whatever()
except:
# this will catch any exception or error
值得一提的是,这不是正确的 Python 编码。这也将捕获许多您可能不想捕获的错误。
首先,您希望它们破坏您的代码的异常(因为当发生此错误时,您的代码无论如何都不会运行!)以及您希望静默/顺利捕获的异常。尝试区分它们。您可能不想捕获所有异常!
其次,您可以花时间查看流程日志,而不是捕获所有内容。假设您收到了一个不同的/第三方异常,例如来自像 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
对于其余部分(可能发生也可能不会发生的错误),如果我遇到意外异常,我将为我的代码崩溃留出空间!通过这种方式,我可以了解正在发生的事情并通过捕获边缘案例来改进我的代码。
如果您希望它永远不会由于某种原因崩溃,例如,如果它是嵌入在您无法轻松访问的远程硬件中的代码,您可以在末尾添加一个通用异常捕获器:
except Exception as e:
print(f"something went wrong! - {e}")
您还可以查看 Python 3 异常层次结构 here。 Exception
和 BaseException
之间的区别在于,Exception
不会捕获 SystemExit
、KeyboardInterrupt
或 GeneratorExit
不定期副业成功案例分享
Exception
的“非异常”。请注意,不可能将int
作为异常引发,并且尝试这样做会引发TypeError
异常,在这种情况下,封闭的except Exception
子句会捕获该异常。另一方面,可以提出旧式类并有资格作为不子类化Exception
的“非异常” - 此 将 被裸except
子句捕获,但not 通过except Exception
子句。TypeError
sys.exit()
通常意味着您希望应用程序终止,但如果您捕获 SystemExit 它不会。同样,如果您在正在运行的脚本(Windows 上的 Ctrl-break)上按下 control-C,您希望程序停止,而不是捕获错误并继续运行。但是,如果您想在存在之前进行清理,您可以捕获其中一个/两个。