Python装饰器知识点补充


Posted in Python onMay 28, 2018

首先回顾一下关于Python装饰器以及装饰器模式

补全

根据Java实现装饰器模式的,我们可以写下面一段代码:

import logging


def use_logging(func):
 logging.warn("%s is running" % func.__name__)
 return func

def foo():
 print('i am foo')

foo = use_logging(foo)

foo() # 调用

这个实现对于上篇文章中提到的Java使用装饰器。上面也是一个装饰器,实现最简单的一个增加函数日志的功能,但是如果这个额外功能是要去检测传入的参数时,这时上面的就不行了。这时12步轻松搞定python装饰器中的例子还是精妙的。

# 装饰器
def wrapper(func):
 def checker(a, b): # 1
  if a.x < 0 or a.y < 0:
   a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0)
  if b.x < 0 or b.y < 0:
   b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0)
  ret = func(a, b)
  if ret.x < 0 or ret.y < 0:
   ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0)
  return ret
 return checker


# 原函数
def add(a, b):
 return Coordinate(a.x + b.x, a.y + b.y)

# 使用装饰 
add = wrapper(add)

细心你会发现,装饰器函数的参数就是传入的原函数,而内部函数的参数跟原函数一模一样,最外层返回的是内部函数的引用,内部函数返回的是传入参数的引用调用的结果

这里用到了函数作为参数特性,当然还有些闭包的知识,具体请看 上面提到的博客链接,真的讲的不错。

而上篇说到的Python装饰 特性就是这个神奇的语法糖了,可以这样使用

# 原函数
@wrapper
def add(a, b):
 return Coordinate(a.x + b.x, a.y + b.y)

带参数的装饰器

如果要实现一个带参数的装饰器,那要怎么写呢

def time_diff(s):
 def decorator(func):
  def wrapper(*args, **kwargs):
   start_time = time.time()
   res = func(*args, **kwargs)
   end_time = time.time()
   print("[%s]执行程序所用时间: %s" % (s, end_time - start_time))
   return res
  return wrapper
 return decorator
 
@time_diff("polynomial_1")
def polynomial_1(n, x):
 res = 0
 for i in range(n):
  res += i*pow(x, i)
 return res

调用并执行输出结果:

print(polynomial_1(1, 5))

[duoxiangshi_1]执行程序所用时间: 4.76837158203125e-06
0

带参数的装饰器需要在不带参数装饰器外再定义一层函数,最外层函数的返回值是第二层函数的引用。

总结:多些多练,用于实际中,才能更加熟练。最近学数据结构与算法,写些装饰器用来看程序执行时间,真是再方便不过了!

Python 相关文章推荐
python远程登录代码
Apr 29 Python
Python中的列表知识点汇总
Apr 14 Python
Python实现基于权重的随机数2种方法
Apr 28 Python
Python上传package到Pypi(代码简单)
Feb 06 Python
Ubuntu 16.04 LTS中源码安装Python 3.6.0的方法教程
Dec 27 Python
pandas实现选取特定索引的行
Apr 20 Python
python实现单链表中删除倒数第K个节点的方法
Sep 28 Python
matplotlib实现热成像图colorbar和极坐标图的方法
Dec 13 Python
python 计算两个列表的相关系数的实现
Aug 29 Python
python list数据等间隔抽取并新建list存储的例子
Nov 27 Python
django下创建多个app并设置urls方法
Aug 02 Python
Python实现8种常用抽样方法
Jun 27 Python
更换Django默认的模板引擎为jinja2的实现方法
May 28 #Python
django manage.py扩展自定义命令方法
May 27 #Python
python实现windows下文件备份脚本
May 27 #Python
django 解决manage.py migrate无效的问题
May 27 #Python
关于django 数据库迁移(migrate)应该知道的一些事
May 27 #Python
解决Django migrate No changes detected 不能创建表的问题
May 27 #Python
django 在原有表格添加或删除字段的实例
May 27 #Python
You might like
PHP 检查扩展库或函数是否可用的代码
2010/04/06 PHP
基于php伪静态的实现详细介绍
2013/04/28 PHP
PHP页面中文乱码分析
2013/10/29 PHP
thinkphp中AJAX返回ajaxReturn()方法分析
2016/12/06 PHP
自定义Laravel (monolog)日志位置,并增加请求ID的实现
2019/10/17 PHP
推荐dojo学习笔记
2007/03/24 Javascript
JS高级笔记
2011/07/13 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
原生JS实现左右箭头选择日期实例代码
2017/03/14 Javascript
vue 自定义 select内置组件
2018/04/10 Javascript
vue异步加载高德地图的实现
2018/06/19 Javascript
移动端滑动切换组件封装 vue-swiper-router实例详解
2018/11/25 Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
2018/12/12 Javascript
详解Vue demo实现商品列表的展示
2019/05/07 Javascript
详解nginx配置vue h5 history去除#号
2020/11/09 Javascript
JavaScript 中的六种循环方法
2021/01/06 Javascript
python使用socket远程连接错误处理方法
2015/04/29 Python
完美解决Python2操作中文名文件乱码的问题
2017/01/04 Python
一篇文章搞定Python操作文件与目录
2019/08/13 Python
Python使用字典实现的简单记事本功能示例
2019/08/15 Python
Python turtle绘画象棋棋盘
2019/08/21 Python
利用python实现.dcm格式图像转为.jpg格式
2020/01/13 Python
matplotlib 多个图像共用一个colorbar的实现示例
2020/09/10 Python
台湾旅游网站:灿星旅游
2018/10/11 全球购物
如何用Java实现列出某个目录下的所有子目录
2015/07/20 面试题
金融专业大学生自我评价
2014/01/09 职场文书
班级口号大全
2014/06/09 职场文书
计算机毕业生求职信
2014/06/10 职场文书
2014年租房协议书范本
2014/10/30 职场文书
2014年保安个人工作总结
2014/11/13 职场文书
幼儿园感谢信
2015/01/21 职场文书
介绍信格式
2015/01/30 职场文书
工作失职自我检讨书
2015/05/05 职场文书
企业廉洁教育心得体会
2016/01/20 职场文书
MySQL 不等于的三种使用及区别
2021/06/03 MySQL
JavaScript实现简单拖拽效果
2021/09/15 Javascript