【问题标题】:exception handling decorator which accepts functions as args接受函数作为参数的异常处理装饰器
【发布时间】:2019-05-13 07:47:50
【问题描述】:

我有一个异常处理装饰器,如下所示:

def error_handler(errors=(Exception, ), default=""):
    def funcator(func):
        def deep_inside(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except errors as e:
                print("i just cought a", repr(e))
                return default
        return deep_inside
    return funcator

这是一个示例用法:

date_error_handler = error_handler((ValueError), default="INVALID")

from dateutil import parser

@date_error_handler
def date_parser(date):
    return parser.parse(date)

现在如果我通过这样的事情:

date_parser("12/10/1O")

我会得到这样的输出:

#output: 

i just cought a ValueError('Unknown string format:', '12/1O/10')
'INVALID'

而不是返回"INVALID",我想将一个函数作为参数传递给default(在error_handler 装饰器中),它将获取日期字符串并尝试用数字替换其中是否存在任何字母。例如,它看起来像这样:

#alphabet to number replacing function(just for example)
def alpha_to_num(date): return date.replace("O", "0")

现在我需要将此alpha_to_num 作为参数传递给error_handlerdefault 参数。

以下是预期输出和用法的示例:

这是一个示例用法:

from dateutil import parser

@error_handler((ValueError), default=alpha_to_num)
def date_parser(date):
    return parser.parse(date)

但现在我想得到这样的输出:

#expected output: 

i just cought a ValueError('Unknown string format:', '12/1O/10')
'12/10/10'

我该如何做这样的事情?

【问题讨论】:

  • 那么预期的输出是什么?
  • 基本上是固定输出。 (上面最后一个代码块)
  • 澄清一下:你想让default总是成为一个函数吗?或者您想同时支持“纯值”和函数默认值?如果您总是希望default 成为一个函数,只需将return default 更改为return default(*args, **kwargs)。要支持这两种类型的值,这取决于您要如何处理一些对冲案例...我个人会使用两个不同的参数,以便在您创建装饰器时清楚哪种情况。这也允许有固定的函数类型的默认值,这很难用一个用于两种情况的参数来处理。
  • 装饰函数的参数可以作为 *args 参数中的元组访问。而不是return default,只需返回args[0]

标签: python python-3.x python-decorators


【解决方案1】:

您正在返回函数而不是调用该函数。使用下面的代码。

edit : 如果函数值未传递或传递的值不是函数,则添加处理。

def error_handler(errors=(Exception, ), default=""):
    def funcator(func):
        def deep_inside(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except errors as e:
                print("i just cought a", repr(e))
                return default(*args, **kwargs) if hasattr(default,'__call__') else default
        return deep_inside
    return funcator

【讨论】:

  • 如果他不指定任何默认值会发生什么?
  • 如果默认为空字符串,为什么要返回 None?
  • 已编辑的答案以在未传递默认值或默认值不是函数时进行处理。
  • 这对类失败:error_handler(default=list)。在这种情况下,它将返回 list 作为默认值,而不是返回包含传递给函数的参数的列表。
猜你喜欢
  • 2016-12-14
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 2016-01-30
  • 2015-09-03
  • 2020-04-02
  • 2015-08-14
  • 2020-01-10
相关资源
最近更新 更多