functools之update_wrapper的使用

栏目: Python · 发布时间: 8年前

内容简介:functools之update_wrapper的使用

我记得5年前来搜狐面试时一个问题就是关于装饰器如何保持函数签名的问题。

由来

xadmin通过实现自己的BaseAdminView(继承自Django的View)来完成xadmin后台界面的处理。在解决一个csrf的问题时,翻了下xadmin BaseAdminView和Django的View部分的代码,关键点少了一条 update_wrapper 使用。导致我的小伙伴调试了半天。

还是看代码

可以对比看下:

## xadmin代码
@classonlymethod
def as_view(cls):
    def view(request, *args, **kwargs):
        self = cls(request, *args, **kwargs)

        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get

        if self.request_method in self.http_method_names:
            handler = getattr(
                self, self.request_method, self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed

        return handler(request, *args, **kwargs)

    # take name and docstring from class
    update_wrapper(view, cls, updated=())
    view.need_site_permission = cls.need_site_permission

    return view

### django/views/generic/base.py:class View中的代码
@classonlymethod
def as_view(cls, **initkwargs):
    """Main entry point for a request-response process."""
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError("You tried to pass in the %s method name as a "
                            "keyword argument to %s(). Don't do that."
                            % (key, cls.__name__))
        if not hasattr(cls, key):
            raise TypeError("%s() received an invalid keyword %r. as_view "
                            "only accepts arguments that are already "
                            "attributes of the class." % (cls.__name__, key))

    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)
    view.view_class = cls
    view.view_initkwargs = initkwargs

    # take name and docstring from class
    update_wrapper(view, cls, updated=())

    # and possible attributes set by decorators
    # like csrf_exempt from dispatch
    update_wrapper(view, cls.dispatch, assigned=())    ## 差了这个啊!同学们
    return view

xadmin是直接把dispatch的代码放到内部的view中了,这样看起来直观,但是缺少了对外可配置(通过重写增加装饰器)的dispatch函数。导致无法对view进行csrf_exempt装饰(其实是dispatch上装饰@csrf_exempt时,装饰器返回的inner上会设置csrf_exempt = True的属性)。

update_wrapper的用法

上述代码应该挺明显了,update_wrapper的作用就是把 cls.dispatch 上的所有属性全部赋值到装饰函数上,也就是代码中的 view

Python 中有几个库是“居家旅行”必备的,functools就是之一,其中的partial也十分有用,用法参考这里 python中functools宝库下的partial

参考

----EOF-----

扫码关注,或者搜索微信公众号:码农悟凡

functools之update_wrapper的使用

以上所述就是小编给大家介绍的《functools之update_wrapper的使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Out of their Minds

Out of their Minds

Dennis Shasha、Cathy Lazere / Springer / 1998-07-02 / USD 16.00

This best-selling book is now available in an inexpensive softcover format. Imagine living during the Renaissance and being able to interview that eras greatest scientists about their inspirations, di......一起来看看 《Out of their Minds》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具