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

发布于 2024-11-06 04:28:31 字数 1441 浏览 1 评论 0原文

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

逻辑是:

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() 具有以下签名:

def render_to_response(*args, **kwargs)

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

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)

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

顺便说一句, render_to_response() 的代码让我觉得有点奇怪。这里是:

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)

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

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

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:

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?

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

慈悲佛祖 2024-11-13 04:28:31

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

如何提取某些论点并传递其他论点的方法实际上取决于您正在做什么。没有一种“正确”的方法可以始终做到这一点。当然,不同的作者有自己偏好的约定。

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

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

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

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.

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.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文