当输入是非法的时,如何输出法律论点列表



我需要实现许多具有这样的案例选择的功能:

def foo1(bar1):
    if bar1 == 'A':
        do something
    elif bar1 == 'B':
        do something
    elif ...
    ...
    else:
        raise ValueError('legal input of bar1 should be {}'.format(list_of_bar))
def foo2(bar2):
    if bar2 == 'A':
        do something
    elif bar2 == 'B':
        do something
    elif ...
    ...
    else:
        raise ValueError('legal input of bar2 should be {}'.format(list_of_bar))
'''

根据"不要自己重复",是否有任何方法可以避免重复提出错误的最后一步并打印正确的参数列表?我认为装饰员可能会这样做,但不确定如何制作。预先感谢。

更新

我自己使用Inspect模块实施了它。但是我仍然希望能得到一些建议或更好的解决方案

import inspect
from functools import wraps
import re
def test_none(func):
    _code = inspect.getsource(func)
    _list = re.findall(r'if (w+) == (w+)', _code)
    assert all(_list[0][0] == name for name, case in _list)
    _arg = _list[0][0]
    _case = tuple(case for name, case in _list)
    @wraps(func)
    def wrapper(*args, **kwargs):
        results = func(*args, **kwargs)
        if results is None:
            raise ValueError(
                    'Legal value of '{arg}' should be anyone of {case}'.format(
                    arg=_arg, case=_case))
        return results
    return wrapper
@test_none
def foo(bar):
    if bar == 0:
        return 1
    elif bar == 1:
        return 2

测试示例:

foo(3)
ValueError: Legal value of 'bar' should be anyone of ('0', '1')

我通常发现'许多情况'模式更清楚地用字典表达。

我会在这里假设,对于每种情况,我们都有不同的函数要调用,但是如果每个值只是要返回的整数或任何其他对象,则模式可行。

例如。 CASES词典清楚,紧凑地向代码的读者发出不同的信号。

CASES = {
    'A': do_something,
    'B': do_something_else,
    ...
}
def foo(bar):
    if bar not in CASES:
        raise ValueError('legal input of bar should be {}'.format(list_of_bar))
    # do stuff
    CASES[bar]()

另一种选择是使用"要求宽恕,而不是许可"模式。我发现在这种特殊情况下,它并不像上面那么清楚。

def foo(bar):
    try:
        func = CASES[bar]
    except KeyError:
        raise ValueError(...)
    # do stuff
    func()

或使用字典.get方法作为另一种方式,但我认为这不如这种特定情况的第一种方式。

def foo(bar):
    func = CASES.get(bar)
    if func is None:
         raise ValueError(...)
    # do stuff
    func()

使用字典将可能的输入映射到操作,类似的东西:

def foo(bar):
    def a():
        print('a():')
    def b():
        print('b():')
    def c():
        print('c():')
    actions = {'A': a, 'B': b, 'C': c}
    if bar in actions:
        actions[bar]()
    else:
        raise ValueError('legal input of bar should be {}'.format(sorted(actions.keys())))

演示:

>>> foo('A')
a():
>>> foo('Z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "x.py", line 15, in foo
    raise ValueError('legal input of bar should be {}'.format(sorted(actions.keys())))
ValueError: legal input of bar should be ['A', 'B', 'C']

最新更新