使函数具有容限性的函数装饰器(函数无声地失败)。
tolerance的Python项目详细描述
- 作者
- alisue<;lambdalisue@hashnote.net>;
- 支持的python版本
- 2.6、2.7、3.2、3.3、3.4
你经常写下面这样的失败静默代码吗?
try:# do what ever you need...return"foo"except:# fail silentlyreturn""
这类代码通常出现在Django项目或程序中,它们应该 在产品模式下不引发任何异常。
tolerance是一个函数修饰符,用于生成一个容忍函数;一个函数 即使有例外也不会引起任何例外。 这个概念对于生成稳定的产品或prefer_int类型非常有用 使用部分描述的代码。
支票 online documentation 更多细节。
功能
- 将函数转换为容限函数
- 修饰函数返回substitute(默认值为None) 不可调用。 当 它是可调用的。
- 忽略异常可以指定为异常类列表 exceptions参数。
- 当fail_silently=False传递给修饰函数时, 函数不忽略异常(参数名可以更改 通过argument_switch_generator函数实现切换功能)。
用法
假设您需要一个函数将字符串转换为整数 可能的。 如果没有公差,您需要编写如下代码
>>># without tolerance>>>defprefer_int_withot_tolerance(x):...try:...returnint(x)...except:...# fail silently...returnx>>>prefer_int_withot_tolerance(0)0>>>prefer_int_withot_tolerance('0')0>>>prefer_int_withot_tolerance('zero')'zero'
但是,有了公差,您只需编写一行代码,如
>>>fromtoleranceimporttolerate>>>prefer_int=tolerate(lambdax:x)(int)>>>prefer_int(0)0>>>prefer_int('0')0>>>prefer_int('zero')'zero'
或者可以使用tolerate作为PEP-318
中描述的函数装饰符。>>>fromtoleranceimporttolerate>>>@tolerate(lambdax:x)...defprefer_int_318(x):...returnint(x)>>>prefer_int_318(0)0>>>prefer_int_318('0')0>>>prefer_int_318('zero')'zero'
上面的示例代码指定了^{tt8}的substitute参数$ 函数指定函数失败时的返回值。( lambda x: x部分)。 tolerate函数需要几个参数来配置函数 行为。 这些论点将在案例研究中解释,并在api文档中详细说明。
更改日志
- 版本0.1.0
- 初期开发
- 使用Python2.4、2.5、2.7、3.2、3.3进行手动测试
- 版本0.1.1
- switch快捷方式功能已添加
- 支持Python2.4和2.5
- 通过2to3支持Python3.2和3.3
- 使用tox进行测试
案例研究
当函数失败时,如何返回默认值?
- 使用substitute参数指定默认值,如
>>>fromtoleranceimporttolerate>>>@tolerate(substitute='foo')...defraise_exception():...raiseException>>>raise_exception()'foo'
如何根据传递的参数更改默认值?
- 将substitute参数指定为函数
>>>fromtoleranceimporttolerate>>>defsubstitute_function(*args,**kwargs):...# do what ever you need, this example simply return 1st argument...returnargs[0]>>>@tolerate(substitute=substitute_function)...defraise_exception(*args):...raiseException>>>raise_exception('bar','hoge')'bar'
问:如何使函数只忽略几个异常?
- 使用exceptions参数指定将被忽略的异常。
>>>fromtoleranceimporttolerate>>>exceptions_ignored=(...AttributeError,...ValueError,...)>>>@tolerate(exceptions=exceptions_ignored)...defraise_exception(x):...ifx==0:...raiseAttributeError...elifx==1:...raiseValueError...else:...raiseKeyError>>>raise_exception(0)isNoneTrue>>>raise_exception(1)isNoneTrue>>>raise_exception(2)Traceback(mostrecentcalllast):...KeyError
如何禁用修饰函数中的忽略异常?
- 将fail_silently=False传递给修饰函数。
>>>fromtoleranceimporttolerate>>>@tolerate()...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>>raise_exception(fail_silently=False)Traceback(mostrecentcalllast):...KeyError
可以通过指定新的开关函数来更改属性名。 下文将对此进行解释。
如何禁用全局忽略异常?
- 将tolerate.disabled = True设置为全局禁用公差。
>>>fromtoleranceimporttolerate>>>@tolerate()...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>>tolerate.disabled=True>>>raise_exception()Traceback(mostrecentcalllast):...KeyError>>># rollback>>>tolerate.disabled=False
如何禁用复杂mannar中的忽略异常?
- 使用switch参数指定开关函数。
>>>fromtoleranceimporttolerate>>>DEBUG=False>>>defswitch_function(*args,**kwargs):...# do what ever you need, this sample check kwargs and DEBUG...# remove 'fail_silently' attribute and store...fail_silently=kwargs.pop('fail_silently',True)...ifDEBUGornotfail_silently:...# do not ignore exceptions. note that kwargs which does not...# have 'fail_silently' is returned back....returnFalse,args,kwargs...# do ignore exceptions. note that kwargs which does not have...# 'fail_silently' is returned back....returnTrue,args,kwargs>>>@tolerate(switch=switch_function)...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>>raise_exception(fail_silently=False)Traceback(mostrecentcalllast):...KeyError>>>DEBUG=True>>>raise_exception()Traceback(mostrecentcalllast):...KeyError
问:我只想更改属性名,使切换功能过于复杂
- 使用argument_switch_generator来实现开关功能。
>>>fromtoleranceimporttolerate>>>fromtoleranceimportargument_switch_generator>>>switch_function=argument_switch_generator('quiet')>>>@tolerate(switch=switch_function)...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>># you can use `quiet=False` instead of `fail_silently`>>>raise_exception(quiet=False)Traceback(mostrecentcalllast):...KeyError>>># raise_exception does not know fail_silently so ignore>>>raise_exception(fail_silently=False)isNoneTrue>>>#>>># From Version 0.1.1>>>#>>>@tolerate(switch='quiet')...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>>raise_exception(quiet=False)Traceback(mostrecentcalllast):...KeyError>>>raise_exception(fail_silently=False)isNoneTrue
注意
在0.1.1版中,只需将参数名指定为switch 参数,然后tolerant函数将调用 argument_switch_generator内部使用指定的名称。
参见API文档的详细信息
q.我只想在传递fail_silently=True时使函数忽略异常
- 使用default参数告诉argument_switch_generator函数
>>>fromtoleranceimporttolerate>>>fromtoleranceimportargument_switch_generator>>>switch_function=argument_switch_generator('fail_silently',default=False)>>>@tolerate(switch=switch_function)...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTraceback(mostrecentcalllast):...KeyError>>>raise_exception(fail_silently=True)isNoneTrue>>>#>>># From Version 0.1.1>>>#>>>@tolerate(switch=[None,False])...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTraceback(mostrecentcalllast):...KeyError>>>@tolerate(switch={'default':False})...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTraceback(mostrecentcalllast):...KeyError
注意
在0.1.1版中,您只需指定*args或**kwargsof argument_switch_generator到switch参数和tolerant 函数将在内部使用 指定的参数。
请参见有关API文档的详细信息
问:我想在通过verbose=False时禁用忽略异常
- 使用reverse参数告诉argument_switch_generator函数
>>>fromtoleranceimporttolerate>>>fromtoleranceimportargument_switch_generator>>>switch_function=argument_switch_generator('verbose',reverse=True)>>>@tolerate(switch=switch_function)...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>>raise_exception(verbose=True)Traceback(mostrecentcalllast):...KeyError>>>#>>># From Version 0.1.1>>>#>>>@tolerate(switch={'argument_name':'verbose','reverse':True})...defraise_exception():...raiseKeyError>>>raise_exception()isNoneTrue>>>raise_exception(verbose=True)Traceback(mostrecentcalllast):...KeyError
问:即使在修饰函数
中,我也要使用fail_silently参数- 使用keep参数告诉argument_switch_generator函数
>>>fromtoleranceimporttolerate>>>fromtoleranceimportargument_switch_generator>>>switch_function=argument_switch_generator('fail_silently',keep=True)>>>@tolerate(switch=switch_function)...defraise_exception(**kwargs):...if'fail_silently'inkwargs:...raiseKeyError...return'Failed!'>>>raise_exception(fail_silently=True)isNoneTrue>>>raise_exception(fail_silently=False)Traceback(mostrecentcalllast):...KeyError>>>#>>># From Version 0.1.1>>>#>>>@tolerate(switch={'keep':True})...defraise_exception(**kwargs):...if'fail_silently'inkwargs:...raiseKeyError...return'Failed!'>>>raise_exception(fail_silently=True)isNoneTrue>>>raise_exception(fail_silently=False)Traceback(mostrecentcalllast):...KeyError