看《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

《Python cookbook》 “定义一个属性可由用户修改的装饰器” 笔记的更多相关文章

  1. python cookbook第三版学习笔记十八:可由用户修改的装饰器

    定义一个属性可由用户修改的装饰器: 在前面的介绍中使用装饰器来包装函数,这一章来介绍下如何让用户调整装饰器的属性. 首先来看下代码: from functools import wraps,parti ...

  2. Python闭包装饰器笔记

    Python三大器有迭代器,生成器,装饰器,这三个中使用最多,最重要的就是装饰器.本篇将重要从函数嵌套开始讲起,从而引入闭包,装饰器的各种用法等. python中的一切都是一个对象(函数也是) 1.首 ...

  3. Python 装饰器(笔记,非原创)

    定义:本质是函数,为其他函数添加附加功能原则:1.不能修改被装饰的函数的源代码         2.不能修改被装饰的函数的调用方式知识储备:       1.函数即“变量”       2.高阶函数  ...

  4. Python类定义、属性、初始化和析构

    类的定义,属性和方法概念 方法中self的作用和意义 初始化( __init__ ) 和 析构方法( __del__ ) 类的定义 class 类名 实例 实例名 = 类名() 一个“实例”的“特征” ...

  5. createuser - 定义一个新的 PostgreSQL 用户帐户

    SYNOPSIS createuser [ option...] [ username] DESCRIPTION 描述 createuser 创建一个新的 PostgreSQL 用户.只有超级用户(在 ...

  6. python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)

    一.函数名应用 函数名是什么?函数名是函数的名字,本质:变量,特殊的变量. 函数名(),执行此函数. python 规范写法 1. #后面加一个空格,再写内容,就没有波浪线了. 2.一行代码写完,下面 ...

  7. python中对变量的作用域LEGB、闭包、装饰器基本理解

    一.作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域.python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量 ...

  8. python基础之函数进阶之函数作为返回值/装饰器

    因为装饰器需要用到返回函数的知识,所以在这里将返回函数和装饰器合并讲解. 什么是返回函数? 我们知道,一个函数中return可以返回一个或者多个值,但其实,return不仅可以返回值,还可以返回函数. ...

  9. python函数式编程之返回函数、匿名函数、装饰器、偏函数学习

    python函数式编程之返回函数 高阶函数处理可以接受函数作为参数外,还可以把函数作为结果值返回. 函数作为返回值 def laxy_sum(*args): def sum(): ax = 0; fo ...

随机推荐

  1. C#基础,目录

    首先,要说明一下本系列会以使用C#为侧重点,不会系统的.大篇量的去解说一些名词,比如:runtime.IL等.文章会在合适的时候对用到的基本概念进行简述.如果你是初学者,建议你也不要过度的去纠结,等你 ...

  2. ElasticSearch 学习记录之ES几种常见的聚合操作

    ES几种常见的聚合操作 普通聚合 POST /product/_search { "size": 0, "aggs": { "agg_city&quo ...

  3. js+画曲线和圆 并限制圆的渲染范围

    通过三个点的坐标可确定一条双曲线. 公式: 1)y=ax^2+bx+c; 2) y=a(x-k)+h; 通过已知三点可确定a,b,c,h,k 2.通过圆心坐标(a,b)和半径r可确定一个圆,和已知的x ...

  4. Java基础—标识符及命名规范

      什么是标识符符? 凡是可以由自己命名的地方都称为修饰符. 例: 项目名 ,包名 ,类名 .方法名 2.   命名规范. ①    不可使用java关键字和保留字,但是可以包含关键字和保留字. ②  ...

  5. android 自己创建一个凝视模板

    android  自己创建一个凝视模板 作为一名程序猿 不仅要有一个写代码的能力,养成一个良好的编写习惯也是非常重要的. 今天给大家具体介绍一下怎样创建凝视模板,给每一个类和方法都自己手动去凝视信息也 ...

  6. Bootstrap全局CSS样式之排版

    Bootstrap能全然友好的支持html5的文本元素,这里不再赘述,详细可參考我还有一篇文章<html的文本元素总结>,这里主要针对Bootstrap封装好的CSS文本样式做一下汇总. ...

  7. Objective-C 和 Swift 混编项目的小 Tips(一)

    本文主要闲聊一些 Objective-C 和 Swift 混编项目带来的一些潜规则,希望能帮到对此感到疑惑的朋友.下面我们开始进入主题: 命名 官方 Guide 上只是简单叙述(Using Swift ...

  8. MyBatis简单使用

    MyBatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使 ...

  9. 在用python操作mysql时报错:ModuleNotFoundError: No module named 'MySQLdb'

    用Flask+python+mysql写一个小项目 系统 win10 py版本:3.6.1 在配置数据库时报错ModuleNotFoundError: No module named 'MySQLdb ...

  10. Ubuntu安装微信开发者工具

    参考教程:https://ruby-china.org/topics/30339 1.下载nw sdk $ wget -c http://dl.nwjs.io/v0.15.3/nwjs-sdk-v0. ...