跳转到主要内容

一个函数装饰器,使函数具有容错性(函数失败时静默)。

项目描述

Build status Coverage Downloads Latest version Wheel Status Egg Status License
作者

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 silently
    return ""

这类代码常见于Django项目或程序,在产品模式下不应抛出任何异常。

tolerance是一个函数装饰器,可以将函数转换为容错函数;即使存在异常也不会抛出异常的函数。这个概念对于制作稳定的产品或prefer_int类型的代码非常有用,如使用说明部分所述。

请查阅在线文档以获取更多详细信息。

功能

  • 将函数转换为容错函数

  • 当装饰的函数不可调用时,返回substitute(默认为None)。当函数可调用时,返回substitute函数的“返回值”。

  • 可以通过exceptions参数指定要忽略的异常类列表。

  • 当将fail_silently=False传递给装饰的函数时,函数不会忽略异常(可以通过argument_switch_generator函数更改参数名称以创建开关函数)。

安装

使用pip

$ pip install tolerance

使用方法

假设您需要一个函数,当可能时将字符串转换为整数。没有tolerance,您需要编写如下代码

>>> # without tolerance
>>> def prefer_int_withot_tolerance(x):
...     try:
...         return int(x)
...     except:
...         # fail silently
...         return x
>>> prefer_int_withot_tolerance(0)
0
>>> prefer_int_withot_tolerance('0')
0
>>> prefer_int_withot_tolerance('zero')
'zero'

然而,使用tolerance,您只需要编写一行代码

>>> from tolerance import tolerate
>>> prefer_int = tolerate(lambda x: x)(int)
>>> prefer_int(0)
0
>>> prefer_int('0')
0
>>> prefer_int('zero')
'zero'

或者,您可以使用PEP-318中描述的函数装饰器tolerance

>>> from tolerance import tolerate
>>> @tolerate(lambda x: x)
... def prefer_int_318(x):
...     return int(x)
>>> prefer_int_318(0)
0
>>> prefer_int_318('0')
0
>>> prefer_int_318('zero')
'zero'

上面的示例代码指定了tolerate函数的substitute参数,用于指定函数失败时返回的值(lambda x: x部分)。tolerate函数接受多个参数来配置函数的行为。这些参数在案例研究和API文档中有详细说明。

变更日志

版本 0.1.0
  • 初始开发

  • 手动测试了Python 2.4、2.5、2.7、3.2、3.3

版本 0.1.1
  • 添加了switch快捷功能

  • 停止支持Python 2.4和2.5

  • 通过2to3支持Python 3.2和3.3

  • 使用tox进行测试

案例研究

问题:我如何返回函数失败时的默认值?

  1. 使用substitute参数指定默认值,如下

>>> from tolerance import tolerate
>>> @tolerate(substitute='foo')
... def raise_exception():
...     raise Exception
>>> raise_exception()
'foo'

问题:我如何根据传递的参数更改默认值?

  1. substitute参数指定为一个函数

>>> from tolerance import tolerate
>>> def substitute_function(*args, **kwargs):
...     # do what ever you need, this example simply return 1st argument
...     return args[0]
>>> @tolerate(substitute=substitute_function)
... def raise_exception(*args):
...     raise Exception
>>> raise_exception('bar', 'hoge')
'bar'

问题:我如何让函数只忽略几个异常?

  1. 使用exceptions参数指定要忽略的异常。

>>> from tolerance import tolerate
>>> exceptions_ignored = (
...     AttributeError,
...     ValueError,
... )
>>> @tolerate(exceptions=exceptions_ignored)
... def raise_exception(x):
...     if x == 0:
...         raise AttributeError
...     elif x == 1:
...         raise ValueError
...     else:
...         raise KeyError
>>> raise_exception(0) is None
True
>>> raise_exception(1) is None
True
>>> raise_exception(2)
Traceback (most recent call last):
    ...
KeyError

问题:我如何在装饰的函数中禁用忽略异常?

  1. fail_silently=False传递给装饰的函数。

>>> from tolerance import tolerate
>>> @tolerate()
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
    ...
KeyError

您可以通过指定新的切换函数来更改属性名。下面将进行解释。

问题:我如何全局禁用忽略异常?

  1. tolerate.disabled = True设置为全局禁用容忍。

>>> from tolerance import tolerate
>>> @tolerate()
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> tolerate.disabled = True
>>> raise_exception()
Traceback (most recent call last):
    ...
KeyError
>>> # rollback
>>> tolerate.disabled = False

问题:我如何以复杂的方式禁用忽略异常?

  1. 使用switch参数指定切换函数。

>>> from tolerance import tolerate
>>> DEBUG = False
>>> def switch_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)
...     if DEBUG or not fail_silently:
...         # do not ignore exceptions. note that kwargs which does not
...         # have 'fail_silently' is returned back.
...         return False, args, kwargs
...     # do ignore exceptions. note that kwargs which does not have
...     # 'fail_silently' is returned back.
...     return True, args, kwargs
>>> @tolerate(switch=switch_function)
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
    ...
KeyError
>>> DEBUG = True
>>> raise_exception()
Traceback (most recent call last):
    ...
KeyError

问题:我只是想更改属性名,使切换函数过于复杂

  1. 使用argument_switch_generator来创建切换函数。

>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('quiet')
>>> @tolerate(switch=switch_function)
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> # you can use `quiet=False` instead of `fail_silently`
>>> raise_exception(quiet=False)
Traceback (most recent call last):
    ...
KeyError
>>> # raise_exception does not know fail_silently so ignore
>>> raise_exception(fail_silently=False) is None
True
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch='quiet')
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(quiet=False)
Traceback (most recent call last):
    ...
KeyError
>>> raise_exception(fail_silently=False) is None
True

问题:我想仅在fail_silently=True传递时使函数忽略异常

  1. 使用default参数告诉argument_switch_generator函数

>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('fail_silently', default=False)
>>> @tolerate(switch=switch_function)
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
Traceback (most recent call last):
    ...
KeyError
>>> raise_exception(fail_silently=True) is None
True
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch=[None, False])
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
Traceback (most recent call last):
    ...
KeyError
>>> @tolerate(switch={'default': False})
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
Traceback (most recent call last):
    ...
KeyError

问题:我想在verbose=False传递时禁用忽略异常

  1. 使用reverse参数告诉argument_switch_generator函数

>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('verbose', reverse=True)
>>> @tolerate(switch=switch_function)
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(verbose=True)
Traceback (most recent call last):
    ...
KeyError
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch={'argument_name': 'verbose', 'reverse': True})
... def raise_exception():
...     raise KeyError
>>> raise_exception() is None
True
>>> raise_exception(verbose=True)
Traceback (most recent call last):
    ...
KeyError

问题:我想在装饰函数中使用fail_silently参数

  1. 使用keep参数告诉argument_switch_generator函数

>>> from tolerance import tolerate
>>> from tolerance import argument_switch_generator
>>> switch_function = argument_switch_generator('fail_silently', keep=True)
>>> @tolerate(switch=switch_function)
... def raise_exception(**kwargs):
...     if 'fail_silently' in kwargs:
...         raise KeyError
...     return 'Failed!'
>>> raise_exception(fail_silently=True) is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
    ...
KeyError
>>> #
>>> # From Version 0.1.1
>>> #
>>> @tolerate(switch={'keep': True})
... def raise_exception(**kwargs):
...     if 'fail_silently' in kwargs:
...         raise KeyError
...     return 'Failed!'
>>> raise_exception(fail_silently=True) is None
True
>>> raise_exception(fail_silently=False)
Traceback (most recent call last):
    ...
KeyError

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

tolerance-0.1.2.tar.gz (11.2 kB 查看散列)

上传于

由以下支持