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匹配中文的正则表达式
May 11 Python
Python获取二维矩阵每列最大值的方法
Apr 03 Python
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
Apr 19 Python
获取python的list中含有重复值的index方法
Jun 27 Python
python2与python3的print及字符串格式化小结
Nov 30 Python
python使用正则筛选信用卡
Jan 27 Python
Python Pandas数据结构简单介绍
Jul 03 Python
python twilio模块实现发送手机短信功能
Aug 02 Python
Django后台管理系统的图文使用教学
Jan 20 Python
解决Tensorflow sess.run导致的内存溢出问题
Feb 05 Python
scrapy redis配置文件setting参数详解
Nov 18 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
Dec 08 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 采集程序中常用的函数
2009/12/09 PHP
学习php设计模式 php实现适配器模式
2015/12/07 PHP
PHP实现的多维数组去重操作示例
2018/07/21 PHP
HTML 自动伸缩的表格Table js实现
2009/04/01 Javascript
用JavaScript对JSON进行模式匹配 (Part 2 - 实现)
2010/07/17 Javascript
javascript实现上传图片并预览的效果实现代码
2011/04/11 Javascript
javascript动画对象支持加速、减速、缓入、缓出的实现代码
2012/09/30 Javascript
js实现具有高亮显示效果的多级菜单代码
2015/09/01 Javascript
Bootstrap Paginator分页插件与ajax相结合实现动态无刷新分页效果
2016/05/27 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
手机端点击图片放大特效PhotoSwipe.js插件实现
2016/08/24 Javascript
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
bootstrap table表格插件使用详解
2017/05/08 Javascript
vue.js学习之UI组件开发教程
2017/07/03 Javascript
vue.js组件之间传递数据的方法
2017/07/10 Javascript
使用3D引擎threeJS实现星空粒子移动效果
2020/09/13 Javascript
vue+echarts实现动态绘制图表及异步加载数据的方法
2018/10/17 Javascript
Node.js实现简单的爬取的示例代码
2019/06/25 Javascript
[02:08]2018年度CS GO枪械皮肤设计大赛优秀作者-完美盛典
2018/12/16 DOTA
详细解析Python当中的数据类型和变量
2015/04/25 Python
Windows下python3.7安装教程
2018/07/31 Python
pandas 空的dataframe 插入列名的示例
2018/10/30 Python
python 使用值来排序一个字典的方法
2018/11/16 Python
对pandas通过索引提取dataframe的行方法详解
2019/02/01 Python
python中对_init_的理解及实例解析
2019/10/11 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
2020/03/30 Python
如何在mac下配置python虚拟环境
2020/07/06 Python
python判断一个变量是否已经设置的方法
2020/08/13 Python
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
澳大利亚香水在线商店:City Perfume
2020/09/02 全球购物
英国珠宝和手表专家:Pleasance & Harper
2020/10/21 全球购物
工作迟到检讨书
2014/02/21 职场文书
网站出售协议书范文
2014/10/10 职场文书
2015年大学迎新工作总结
2015/07/16 职场文书
springboot如何接收application/x-www-form-urlencoded类型的请求
2021/11/02 Java/Android