Python:在包装函数中使用* args,** kwargs

时间:2021-08-25 21:26:18

I'm writing a wrapper function for Django's render_to_response() to add a CSRF processing.

我正在为Django的render_to_response()编写一个包装函数来添加CSRF处理。

The logic is:

逻辑是:

def some_view (request)
    dictionary = {'context_param': some_param}
    dictionary.update(csrf(request))
    # ... view code here
    return render_to_response("a_template.html", dictionary)

render_to_response() has the following signature:

render_to_response()具有以下签名:

def render_to_response(*args, **kwargs)

I want to write transparent wrapper - just add some functionality (mentioned before) and leave other things as they are. I guess I should write someting like this:

我想写透明包装器 - 只需添加一些功能(前面提到过)并保留其他内容。我想我应该写这样的东西:

def csrf_response (request, *args, **kwargs):

    # Here I need to somehow extract dictionary from args or kwargs

    if dictionary is None:
        dictionary = {}
    dictionary.update(csrf(request))

    # And here I somehow need to pass dictionary into render_to_response() fot the furher processing
    return render_to_response(*args, **kwargs)

So question is - what is the best practice for extracting needed parameter from args/kwargs, (then changing it) and passing it further?

所以问题是 - 从args / kwargs中提取所需参数(然后更改它)并将其进一步传递的最佳实践是什么?

BTW code of render_to_response() seemed me a bit strange. Here it is:

render_to_response()的BTW代码似乎有点奇怪。这里是:

def render_to_response(*args, **kwargs):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)

What if someone call it with all positional arguments, so kwargs will be empty, but mimetype parameter will be specified as a last positional argument? Looks like in that case its behavior would be wrong.

如果有人用所有位置参数调用它,那么kwargs将为空,但mimetype参数将被指定为最后一个位置参数?看起来在这种情况下它的行为是错误的。

1 个解决方案

#1


6  

Because of how render_to_response is implemented, the only way to specify mimetype is by using a named argument. Anything passed as a positional argument will be passed on to loader.render_to_string.

由于实现了render_to_response,指定mimetype的唯一方法是使用命名参数。作为位置参数传递的任何内容都将传递给loader.render_to_string。

The methodology for how to go about extracting certain arguments and passing on others really depends on what you're doing. There's no one "correct" way to always do it. Naturally, different authors have their own preferred conventions.

如何提取某些论点并传递其他论点的方法实际上取决于你正在做什么。没有一种“正确”的方法可以永远这样做。当然,不同的作者有自己的首选惯例。

In the place of your comment # Here I need to somehow extract dictionary from args or kwargs you can use kwargs directly as a dictionary, and args as a tuple, because that's exactly what they are. For the args, you have no choice but to assert (i.e. assume) the meaning of the value in each position.

在你的评论的位置#在这里,我需要以某种方式从args或kwargs中提取字典,你可以直接使用kwargs作为字典,并将args作为元组,因为这正是它们的本质。对于args,你别无选择,只能断言(即假设)每个位置的值的含义。

I personally prefer that if you are writing code that knows the values of certain arguments, they should be declared in the signature, like so:

我个人更喜欢,如果你编写的代码知道某些参数的值,那么它们应该在签名中声明,如下所示:

def spam(session, name, *args, clear=True, **kwargs):
  # do something with session, name, clear
  return eggs(name, *args, **kwargs)  # if eggs requires name

#1


6  

Because of how render_to_response is implemented, the only way to specify mimetype is by using a named argument. Anything passed as a positional argument will be passed on to loader.render_to_string.

由于实现了render_to_response,指定mimetype的唯一方法是使用命名参数。作为位置参数传递的任何内容都将传递给loader.render_to_string。

The methodology for how to go about extracting certain arguments and passing on others really depends on what you're doing. There's no one "correct" way to always do it. Naturally, different authors have their own preferred conventions.

如何提取某些论点并传递其他论点的方法实际上取决于你正在做什么。没有一种“正确”的方法可以永远这样做。当然,不同的作者有自己的首选惯例。

In the place of your comment # Here I need to somehow extract dictionary from args or kwargs you can use kwargs directly as a dictionary, and args as a tuple, because that's exactly what they are. For the args, you have no choice but to assert (i.e. assume) the meaning of the value in each position.

在你的评论的位置#在这里,我需要以某种方式从args或kwargs中提取字典,你可以直接使用kwargs作为字典,并将args作为元组,因为这正是它们的本质。对于args,你别无选择,只能断言(即假设)每个位置的值的含义。

I personally prefer that if you are writing code that knows the values of certain arguments, they should be declared in the signature, like so:

我个人更喜欢,如果你编写的代码知道某些参数的值,那么它们应该在签名中声明,如下所示:

def spam(session, name, *args, clear=True, **kwargs):
  # do something with session, name, clear
  return eggs(name, *args, **kwargs)  # if eggs requires name