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 10 Python
Python爬虫实例_城市公交网络站点数据的爬取方法
Jan 10 Python
Python实现的网页截图功能【PyQt4与selenium组件】
Jul 12 Python
python实现zabbix发送短信脚本
Sep 17 Python
python使用folium库绘制地图点击框
Sep 21 Python
python三引号输出方法
Feb 27 Python
python urllib爬虫模块使用解析
Sep 05 Python
python验证码图片处理(二值化)
Nov 01 Python
python异常处理之try finally不报错的原因
May 18 Python
在python3.64中安装pyinstaller库的方法步骤
Jun 02 Python
如何基于Python和Flask编写Prometheus监控
Nov 25 Python
matplotlib绘制多子图共享鼠标光标的方法示例
Jan 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修正代码
2011/05/09 PHP
学习php设计模式 php实现工厂模式(factory)
2015/12/07 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
TP3.2框架分页相关实现方法分析
2020/06/03 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
getElementById在任意一款浏览器中都可以用吗的疑问回复
2007/05/13 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
2013/12/05 Javascript
jQuery在iframe中无法弹出对话框的解决方法
2014/01/12 Javascript
JavaScript实现多个重叠层点击切换效果的方法
2015/04/24 Javascript
JQuery中DOM实现事件移除的方法
2015/06/13 Javascript
javascript中sort() 方法使用详解
2015/08/30 Javascript
jquery ajax分页插件的简单实现
2016/01/27 Javascript
AngularJS实现表单验证功能
2017/01/09 Javascript
微信小程序中的swiper组件详解
2017/04/14 Javascript
js实现以最简单的方式将数组元素添加到对象中的方法
2017/12/20 Javascript
基于form-data请求格式详解
2019/10/29 Javascript
JS实现导航栏楼层特效
2020/01/01 Javascript
python通过socket查询whois的方法
2015/07/18 Python
Python实现定时任务
2017/02/08 Python
Python实现学校管理系统
2018/01/11 Python
pandas按若干个列的组合条件筛选数据的方法
2018/04/11 Python
python用BeautifulSoup库简单爬虫实例分析
2018/07/30 Python
python如何求解两数的最大公约数
2018/09/27 Python
Django csrf 验证问题的实现
2018/10/09 Python
python爬虫增加访问量的方法
2019/08/22 Python
Python Django2.0集成Celery4.1教程
2019/11/19 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
2020/03/10 Python
python文件排序的方法总结
2020/09/13 Python
如何通过python实现IOU计算代码实例
2020/11/02 Python
Python开发.exe小工具的详细步骤
2021/01/27 Python
公司爱心捐款倡议书
2014/05/14 职场文书
会计专业自荐书
2014/07/08 职场文书
2016感恩父亲节主题广播稿
2015/12/18 职场文书
python 统计代码耗时的几种方法分享
2021/04/02 Python
如何将numpy二维数组中的np.nan值替换为指定的值
2021/05/14 Python
Java 定时任务技术趋势简介
2022/05/04 Java/Android