与装饰器和正常功能相同的条件?

时间:2012-04-23 22:15:24

标签: django function decorator

我想针对正则表达式模式检查某个参数值,只有匹配时才会继续。这发生在我的应用程序中的许多地方,所以我决定让一个函数执行检查并在需要时调用该函数。现在,在大多数情况下,我需要在视图的开头执行检查,因此我将其创建为装饰器,如下所示:

def validate(f):
    def _inner(request, argument=None):
        if argument is None:
            return HttpResponse(content="No argument given", status=400)
        elif not re.match('^SOME_REGEX$', argument):
            return HttpResponse(content="Invalid argument", status=400)
        else:
            return f(request, argument)
    return _inner

但是在其他情况下我需要从 函数中调用该检查器,作为嵌套条件的一部分。我似乎无法直接调用它,例如validate(argument)。有什么方法可以使用相同的代码作为装饰器以及正常的功能?或者我必须输入两次?

1 个答案:

答案 0 :(得分:3)

你当然不必输入两次,你可以创建一个validate函数,它接受一个值并验证它:

def validate(argument):
    return re.match('^SOME_REGEX$', argument)

然后编写一个装饰器,根据需要调用validate函数:

def requires_valid(f):
    def _inner(request, argument=None):
        if argument is None:
            return HttpResponse(content="No argument given", status=400)
        elif not validate(argument):
            return HttpResponse(content="Invalid argument", status=400)
        else:
            return f(request, argument)
    return _inner

显然,我不知道您的用例,因此您可能希望将None的检查移至validate,但重点是,您不必重复相同的正则表达式两次。

如果您想深入研究更深层的魔法,并坚持使用相同的功能作为装饰者和验证者,您可以尝试这样的事情:

def validate(f):
    if callable(f):
        def _inner(request, argument=None):
            if argument is None:
                return HttpResponse(content="No argument given", status=400)
            elif not validate(argument):
                return HttpResponse(content="Invalid argument", status=400)
            else:
                return f(request, argument)
        return _inner
    else:
        return re.match('^SOME_REGEX$', f)

但是我建议不要这样做,因为你有一个函数可以执行两个非常不同的操作,具体取决于参数的类型。这导致代码更难以理解。 (“你用这个函数装饰一个视图,它接受一个字符串并返回bool?!”)