zoukankan      html  css  js  c++  java
  • 《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记

    看《Python cookbook》的时候,第9.5部分,“定义一个属性可由用户修改的装饰器”,有个装饰器理解起来花了一些时间,做个笔记免得二刷这本书的时候忘了

    完整代码:https://github.com/blackmatrix7/python-learning/blob/master/python_cookbook/chapter_9/section_5/attach_wrapper.py

    书中的装饰器(书中称之为访问器函数)

    def attach_wrapper(obj, func=None):
        if func is None:
            return partial(attach_wrapper, obj)
        setattr(obj, func.__name__, func)
        return func

    这个访问器函数,接受两个参数,obj是需要处理的对象,func是被装饰的函数。实现的效果是将被装饰的对象,附加到obj中,使obj这个对象具有func这个方法。

    当访问器函数,执行到func is None时,实际上是执行的是attach_wrapper(obj=wrapper),刚刚将需要处理的对象obj传入。

            @attach_wrapper(wrapper)
            def set_message(newmsg):
                print('set message')
                nonlocal logmsg
                logmsg = newmsg

    如果对装饰器有一定理解,上面的set_message的装饰器,实际上等于下面的方法

    attach_wrapper(wrapper)(set_message)

    对上面这个语句,还可以继续拆分

    访问器函数中判断,当func为None时,返回一个偏函数 return partial(attach_wrapper, obj)

    这个偏函数实际上是生成了一个包装器,包装器本身接受被装饰的函数。

    所以我们得到一个偏函数,也是包装器

    partial_func = partial(attach_wrapper, obj)
    attach_wrapper(wrapper) == partial_func

    因为偏函数已经带有一个obj参数, 所以再次调用时,执行 setattr(obj, func.__name__, func)

    此时给装饰器传入的对象,附加上被装饰的函数

    partial_func(set_message)

    如果还不明白,可以看下面的装饰器。

    这个装饰器的功能,等价于上面的访问器函数

    def my_attach_wrapper(obj):
        """
        如果这样写就非常容易理解了,把这个方法附加到被传入的对象中
        :param obj: 
        :return: 
        """
        def _my_attach_wrapper(func):
                setattr(obj, func.__name__, func)
        return _my_attach_wrapper
  • 相关阅读:
    redis key命名规范
    git修改commit作者名
    spring cloud 入门学习
    IDEA 插件大全
    2019 java中高级 面试题汇总
    Spring boot整合Mybatis【详细的一匹】
    MySQL存储过程
    HTTP状态码详解
    java 职业规划
    javaweb项目实现文件上传下载
  • 原文地址:https://www.cnblogs.com/blackmatrix/p/6850762.html
Copyright © 2011-2022 走看看