假设我想提出一个异常并提供额外的处理信息;最好的做法是什么?
我想出了以下方法,但对我来说有点可疑:
def internal_function():
raise ValueError("smelly socks!")
def context_function():
try:
internal_function()
except Exception as e:
e.args= e.args[:1] + ("<raise_context>",) + e.args[1:] # raise context varies on conditions ofc
raise e
def handler_function():
try:
context_function()
except Exception as e:
msg, context, *other = e.args
if context == "some_context":
pass # handle one way
elif context == "some other context":
pass # handle another way
仅供参考,不是重复的 如何在 Python 中向异常添加上下文|| |,因为发布者想要修改消息字符串而不是添加单独的元数据。 , since there the poster wants to amend the message string rather than adding separate metadata.
虽然你的方法有效,但它不是最干净或最符合 Python 风格的方式。修改
Exception.args
属性直接被认为是不好的做法,因为它可能导致一些依赖于异常参数结构的调试器或日志记录工具出现意外行为。
以下是更符合 Python 风格的处理此问题的替代方法:
- 使用自定义异常:
这是最干净和最灵活的方法。通过创建一个继承自内置
Exception
类的自定义异常,你可以添加特定于你的用例的额外属性:
```python class MyContextualException(Exception): def init (self, message, context=None): super(). init (message) self.context = context
def internal_function(): raise MyContextualException("smelly socks!", context="<raise_context>")
def context_function(): try: internal_function() except MyContextualException as e: # 处理上下文 if e.context == "<some_context>": pass # 以某种方式处理 elif e.context == "<some other context>": pass # 以另一种方式处理 raise # 重新引发以供进一步处理或记录 ```
-
使用
raise ... from ...
语法(用于隐式上下文):
如果你不需要处理特定于上下文的逻辑,但希望提供更多关于异常原因的信息,请使用
raise ... from ...
语法。这将保留原始异常的回溯,同时提供有关其发生上下文的额外信息:
```python def internal_function(): raise ValueError("smelly socks!")
def context_function(): try: internal_function() except ValueError as e: raise RuntimeError("在 context_function 中出现问题") from e ```
在这种情况下,最终的异常消息将指示
RuntimeError
是由于
ValueError
引起的,从而提供更多上下文。
- 使用日志记录库(用于调试和外部上下文):
对于调试或添加不能轻松编码为异常属性的丰富上下文信息,日志记录库(如 Python 的内置
logging
模块)非常有用:
```python import logging
def internal_function(): logging.debug("即将引发 ValueError") raise ValueError("smelly socks!")
def context_function(): try: internal_function() except ValueError as e: logging.exception("在 context_function 中捕获到 ValueError") raise # 重新引发以供进一步处理 ```
此方法提供了详细的日志,其中包含异常信息以及发生异常时执行流程的上下文,这在调试或理解生产环境中出现的问题时非常有价值。
请记住,最佳方法取决于你的具体需求。自定义异常提供最大的灵活性和明确性,而
raise ... from ...
和日志记录提供了用于添加上下文的更简单方法。