【问题标题】:How to make exception handling code reusable without decorators?如何在没有装饰器的情况下使异常处理代码可重用?
【发布时间】:2020-11-06 09:34:26
【问题描述】:

我有异常处理代码被复制并粘贴到多个地方,例如

def get(self, id):

    try:
         response = self.client_module_property.get(id)
    except APIItemNotFoundException:
         print("'{}' does not exist.".format(id), file=sys.stderr)
         sys.exit(1)
    except Exception as e:
         print(
             "Unknown error. To debug run with env var LOG_LEVEL=DEBUG",
             file=sys.stderr,
         )
         _log.error(e)
         sys.exit(1)
    ...

还有……

def delete(self, id):

    try:
         self.client_module_property.delete(id=id)
    except APIItemNotFoundException:
         print("'{}' does not exist".format(id), file=sys.stderr)
         sys.exit(1)
    except Exception as e:
         print(
             "Unknown error. To debug run with env var LOG_LEVEL=DEBUG",
             file=sys.stderr,
         )
         _log.error(e)
         sys.exit(1)

我研究过装饰器,但它们对我来说不是一个好选择,因为我正在反省其他代码中的函数参数并且装饰器会更改方法签名。

还有其他方法可以提取异常处理代码以使其可重用吗?

question 中的 cmets 建议可以在此处使用上下文管理器,但我不清楚浏览 python 文档会是什么样子。

该解决方案需要在 Python 2.7 和 3.x 上运行

【问题讨论】:

标签: python


【解决方案1】:

最后,我和wrapt 一起工作了。我发布我的解决方案以防它对其他人有用。

最后,只要能拿到方法参数,重用装饰器其实是可以的。

我的装饰师:

@wrapt.decorator
def intercept_exception(wrapped, instance, args, kwargs):
    """Handle Exceptions."""
    try:
        return wrapped(*args, **kwargs)
    except AssertionError as ae:
        print(ae, file=sys.stderr)
        sys.exit(1)
    except (
        APIException,
        APIItemNotFoundException,
        ContainerPlatformClientException,
    ) as e:
        print(e.message, file=sys.stderr)
        sys.exit(1)
    except Exception as ge:
        print(
            "Unknown error. To debug run with env var LOG_LEVEL=DEBUG",
            file=sys.stderr,
        )
        _log.error(ge)
        sys.exit(1)

装饰函数:

@intercept_exception
def get(self, id):
    response = self.client_module_property.get(id)
    ...

我的客户端代码需要检索方法参数

def get_metadata(self):
    ...
    if six.PY2:
        parameter_names = list(inspect.getargspec(function).args)
    else:
        parameter_names = list(
            inspect.getfullargspec(function).args
        )
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2014-07-18
    相关资源
    最近更新 更多