如何修改存储的参数函数工具.wrapps?

2024-09-28 20:39:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个decorator,它可以验证一些参数,并将经过验证的密钥传递给各种函数:

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

这可用于其他一些功能:

^{pr2}$

我会这样调用函数:

genericHandler(request)

装饰器生成“key”kwarg。但是,我想在其他点传递密钥,即调用:

genericHandler(request, 'keydata')

目前这给了我一个错误:

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

我怎么才能避开这个?重申一下,主要目标是能够使用或不使用可选参数调用genericHandler(),并且只有在缺少参数时,装饰器才会生成该参数。在

到目前为止,在decorator中,我无法确定是否传入了'key'参数,因为工具包装()似乎把它藏起来了。在


Tags: key函数参数returnifrequest密钥args
2条回答

所以对我来说,最好的方法就是显式地将kwargs作为kwargs传递。所以装饰功能实际上应该是:

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

这样,我就可以调用函数,无论是否使用参数:

^{pr2}$

或者

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

如果您希望包装器的签名仍然是(request, *args, **kwargs),那么没有任何合理的方法可以做到这一点。另一方面,看起来您的decorator已经假定包装函数接受一个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参数。在

相关问题 更多 >