4

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

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). 有什么办法可以使用与装饰器和普通函数相同的代码?还是我必须输入两次?

4

1 回答 1

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

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

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

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)

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

于 2012-04-23T22:23:53.113 回答