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 04 Python
python中bisect模块用法实例
Sep 25 Python
跟老齐学Python之关于循环的小伎俩
Oct 02 Python
python结合opencv实现人脸检测与跟踪
Jun 08 Python
Pycharm学习教程(7)虚拟机VM的配置教程
May 04 Python
简单实现Python爬取网络图片
Apr 01 Python
python中字符串变二维数组的实例讲解
Apr 03 Python
python scp 批量同步文件的实现方法
Jan 03 Python
python异步实现定时任务和周期任务的方法
Jun 29 Python
python的debug实用工具 pdb详解
Jul 12 Python
Python把图片转化为pdf代码实例
Jul 28 Python
Python实现淘宝秒杀功能的示例代码
Jan 19 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 session 预定义数组
2009/03/16 PHP
深入密码加salt原理的分析
2013/06/06 PHP
PHP实现自动识别Restful API的返回内容类型
2015/02/07 PHP
PHP模版引擎原理、定义与用法实例
2019/03/29 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
网页禁用右键实现代码(JavaScript代码)
2009/10/29 Javascript
自己使用js/jquery写的一个定制对话框控件
2014/05/02 Javascript
jquery通过select列表选择框对表格数据进行过滤示例
2014/05/07 Javascript
Node.js实现简单聊天服务器
2014/06/20 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
JavaScript中的分号插入机制详细介绍
2015/02/11 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
jQuery的内容过滤选择器学习教程
2016/04/18 Javascript
Vue.js实现文章评论和回复评论功能
2020/05/30 Javascript
Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法
2017/09/20 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
vue全局自定义指令-元素拖拽的实现代码
2019/04/14 Javascript
npm 语义版本控制详解
2019/09/10 Javascript
python集合类型用法分析
2015/04/08 Python
Python中遍历字典过程中更改元素导致异常的解决方法
2016/05/12 Python
Python抓取框架 Scrapy的架构
2016/08/12 Python
python使用super()出现错误解决办法
2017/08/14 Python
详解关于Django中ORM数据库迁移的配置
2018/10/08 Python
Django REST framework 分页的实现代码
2019/06/19 Python
python实现在内存中读写str和二进制数据代码
2020/04/24 Python
pycharm下pyqt4安装及环境配置的教程
2020/04/24 Python
python切片作为占位符使用实例讲解
2021/02/17 Python
斯洛伐克时尚服装网上商店:Cellbes
2016/10/20 全球购物
英国领先的汽车轮胎和快速健康中心:Kwik Fit
2017/10/29 全球购物
财务工作者先进事迹材料
2014/01/17 职场文书
管理岗位竞聘演讲稿
2014/08/18 职场文书
材料员岗位职责范本
2015/04/11 职场文书
烛光里的微笑观后感
2015/06/17 职场文书
教你如何让spark sql写mysql的时候支持update操作
2022/02/15 MySQL
python实现会员信息管理系统(List)
2022/03/18 Python
国际最新研究在陨石中发现DNA主要成分 或由陨石带来地球
2022/04/29 数码科技