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)です。通常の関数だけでなく、デコレータと同じコードを使用できる方法はありますか?または、2回入力する必要がありますか?

4

1 に答える 1

3

確かに2回入力する必要はありません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が、要点は、同じ正規表現を2回繰り返す必要がないということです。

そして、より深い魔法を掘り下げて、デコレータとベリファイアの両方として同じ関数を使用することを主張したい場合は、次のようなことを試してみてください。

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)

ただし、パラメーターのタイプに応じて、2つの非常に異なることを実行する1つの関数があるため、これには反対することをお勧めします。その結果、コードがはるかに理解しにくくなります。(「文字列を受け取り、boolを返すこの関数でビューを装飾しますか?!」)

于 2012-04-23T22:23:53.113 に答える