我如何编写一个可以捕获所有异常的 `try`/`except` 块?
- 2024-12-13 08:36:00
- admin 原创
- 174
问题描述:
我如何编写一个可以捕获所有异常的try
/except
块?
解决方案 1:
除了裸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
:如果你捕获并吞下这些异常,那么任何人都很难退出你的脚本。
解决方案 2:
你可以但你可能不应该:
try:
do_something()
except:
print("Caught it!")
但是,这也会捕获类似这样的异常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
解决方案 3:
要捕获所有可能的异常,请使用 catch BaseException
。它位于 Exception 类层次结构的顶部:
Python 3:
https ://docs.python.org/3.12/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))
但正如其他人提到的,您通常不需要这样做,只有在非常特殊的情况下才需要这样做。
解决方案 4:
你可以这样做来处理一般异常
try:
a = 2/0
except Exception as e:
print e.__doc__
print e.message
解决方案 5:
非常简单的例子,类似于这里的例子:
http://docs.python.org/tutorial/errors.html#defining-clean-up-actions
如果您试图捕获所有异常,则请将所有代码放在“try:”语句中,代替“打印“执行可能引发异常的操作。””。
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)无论是否引发异常,执行 try 语句后都会直接调用 Finally。
3)“抛出了异常!”或“一切看起来都很好!”取决于是否抛出了异常。
希望这有帮助!
解决方案 6:
有多种方法可以做到这一点,特别是在 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()
解决方案 7:
我刚刚发现了这个在 Python 2.7 中测试异常名称的小技巧。有时我在代码中处理了特定的异常,所以我需要进行测试以查看该名称是否在已处理的异常列表中。
try:
raise IndexError #as test error
except Exception as e:
excepName = type(e).__name__ # returns the name of the exception
解决方案 8:
我添加了一个奖励方法,可以捕获带有完整回溯的异常,这可以帮助您更好地理解错误。
Python 3
import traceback
try:
# your code goes here
except Exception as e:
print(e)
traceback.print_exc()
解决方案 9:
try:
whatever()
except:
# this will catch any exception or error
值得一提的是,这不是正确的 Python 编码。这还会捕获许多您可能不想捕获的错误。
解决方案 10:
首先,有些异常您希望它们破坏您的代码(因为当此错误发生时,您的代码无论如何都不会运行!),而有些异常您希望悄无声息地/顺利地捕获。尝试区分它们。您可能不想捕获所有异常!
其次,您可以花时间查看流程日志,而不是捕获所有内容。假设您遇到了不同的/第三方异常,例如来自 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 异常层次结构。Exception
和之间的区别BaseException
在于,Exception
不会捕获SystemExit
、KeyboardInterrupt
或GeneratorExit
扫码咨询,免费领取项目管理大礼包!