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实现将pvr格式转换成pvr.ccz的方法
Apr 28 Python
Python利用splinter实现浏览器自动化操作方法
May 11 Python
python实现淘宝秒杀脚本
Jun 23 Python
django 通过URL访问上传的文件方法
Jul 28 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
Feb 20 Python
Python AutoCAD 系统设置的实现方法
Apr 01 Python
20行Python代码实现视频字符化功能
Apr 13 Python
Python爬虫防封ip的一些技巧
Aug 06 Python
Python xmltodict模块安装及代码实例
Oct 05 Python
让你相见恨晚的十个Python骚操作
Nov 18 Python
如何用 Python 子进程关闭 Excel 自动化中的弹窗
May 07 Python
python数字图像处理之图像的批量处理
Jun 28 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 HandlerSocket的使用
2011/05/02 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
2014/06/25 PHP
PHP实现抓取HTTPS内容
2014/12/01 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
PHP+Javascript实现在线拍照功能实例
2015/07/18 PHP
PHP实现的统计数据功能详解
2016/12/06 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
2018/07/21 PHP
用javascript实现计算两个日期的间隔天数
2007/08/14 Javascript
javascript中的缓动效果实现程序
2012/12/29 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
遍历DOM对象内的元素属性示例代码
2014/02/08 Javascript
2014年最火的Node.JS后端框架推荐
2014/10/27 Javascript
jQuery标签编辑插件Tagit使用指南
2015/04/21 Javascript
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
url传递的参数值中包含&amp;时,url自动截断问题的解决方法
2016/08/02 Javascript
vue组件如何被其他项目引用
2017/04/13 Javascript
详解AngularJS2 Http服务
2017/06/26 Javascript
VUE-cli3使用 svg-sprite-loader
2018/10/20 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
2018/11/13 Javascript
vue路由权限校验功能的实现代码
2020/06/07 Javascript
[04:47]DOTA2-潍坊风行电子俱乐部探秘
2014/08/08 DOTA
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
2018/02/23 Python
Django框架会话技术实例分析【Cookie与Session】
2019/05/24 Python
python进程的状态、创建及使用方法详解
2019/12/06 Python
基于matplotlib中ion()和ioff()的使用详解
2020/06/16 Python
Python如何自动获取目标网站最新通知
2020/06/18 Python
python3.9实现pyinstaller打包python文件成exe
2020/12/13 Python
StubHub意大利:购买和出售全球演唱会和体育赛事门票
2017/11/21 全球购物
简单英文演讲稿
2014/01/01 职场文书
《赠汪伦》教学反思
2014/04/12 职场文书
献爱心活动总结
2014/05/07 职场文书
求职信怎么写
2014/05/23 职场文书
入股协议书范本
2014/11/01 职场文书
汉语拼音教学反思
2016/02/22 职场文书
用Python爬取某乎手机APP数据
2021/06/15 Python
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js