0

いくつかのパラメーターを検証し、検証されたキーをさまざまな関数に渡すデコレーターがあります。

from functools import wraps

ref validate(f):
    @wraps(f) # This is to ensure docstrings are passed through the decorated function
    def redirect_if_invalid(request, *args, **kwargs):
        if request.valid == False:
            return HttpResponseRedirect('/login')
        else:
            newkwargs = { 'key': request.key }
        return f(request, *args, **newkwargs)
return redirect_if_invalid

これは、他のいくつかの関数で使用されます。

@validate
def genericHandler(request, key)
   pass

この関数を次のように呼び出します。

genericHandler(request)

そして、デコレータは「キー」kwarg を生成します。ただし、必要に応じて、別の時点でキーを渡したいと思います。つまり、次のように呼び出します。

genericHandler(request, 'keydata')

現在、これは私にエラーを与えます:

TypeError: genericHandler() got multiple values for keyword argument 'key'

どうすればこれを回避できますか? 繰り返しますが、主な目標は、オプションのパラメーターを指定して、または指定せずに genericHandler() を呼び出せるようにすることと、パラメーターが欠落している場合にのみデコレーターにパラメーターを生成させることです。

functools.wraps() がそれを隠しているように見えるため、これまでデコレータ内で「キー」パラメータが渡されたかどうかを判断する方法がわかりません。

4

2 に答える 2

1

ラッパーの署名をそのままにしたい場合、これを行う合理的な方法はありません(request, *args, **kwargs)。一方、あなたのデコレーターは、ラップされた関数がkeyパラメーターを取ると既に想定しているように見えます。その場合、渡されたかどうかを確認するのは簡単です。

def validate(f):
    @wraps(f)
    def redirect_if_invalid(request, key=None):
        # do the validation
        if key is None:
            key = request.key
        return f(request, key)
    return redirect_if_invalid

*argsもちろん、必要に応じておよび**kwargsパラメータを元に戻すこともできます。

于 2013-09-10T00:30:15.050 に答える
0

したがって、これを行うための最良の方法は、kwargs を明示的に kwargs として渡すことでした。したがって、装飾された関数は実際には次のようになります。

@validate
def genericHandler(request, **kwargs)
    key = kwargs.get('key')
    pass

このようにして、引数の有無にかかわらず関数を呼び出すことができます。

genericHandler(request)

また

genericHandler(request, **{ 'key' : key })

実際の装飾は次のようになります。

def validate(f):
    @wraps(f) # This is to ensure docstrings are passed through the decorated function
    def redirect_if_invalid(request, *args, **kwargs):
        key = kwargs.get('key')
        if not key:
            kwargs.set('key', request.key)
        return f(request, *args, **kwargs)
    return redirect_if_invalid
于 2013-09-10T04:41:31.963 に答える