Python装饰器原理与基本用法分析


Posted in Python onJanuary 07, 2020

本文实例讲述了Python装饰器原理与基本用法。分享给大家供大家参考,具体如下:

装饰器:

意义:在不能改变原函数的源代码,和在不改变整个项目中原函数的调用方式的情况下,给函数添加新的功能

由于不允许改变函数的源代码,在忽略调用方式的情况下,我们可能会有以下结果:

def decorator(func):
  func()
  print("logging")
def test1():
  print("test1")
def test2():
  print("Test2")
decorator(test1)
decorator(test2)

但这改变了原本的调用方式,原本是test1(),现在是decorator(test1)

那么如果我们为了使调用方式不变,是否可以使装饰好的函数decorator的返回值是一个我们需要的函数,再赋值给原来的函数名呢?

于是:

def timmer1(func):
  def warpper():
    start_time = time.time()
    func()
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
   return warpper
test3=timmer1(test3)

好像上面这段代码并没有改变原来的调用方式,调用原来的test3,相当于运行timmer1中的warpper

如果对于无参数的函数来说,上面的代码已经实现了我们的目的,但对于带参数的函数,上面的代码没有传入参数,所以仍然需要修改

于是:

def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper

在上上面的代码中,由于实质上,test3已经等于wrapper,所以可以直接使用,test3(参数)来传入参数,为了处理参数不确定数量问题,可以使用可变长度参数

上面代码还存在一个问题,无法获取原本函数中的返回值,那么我们还需要加上一些东西:

import time
def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    return res
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper

使用一个变量记录下原函数的返回值。

这样我们就实现了装饰器的基本功能。

补充:

python提供了一个功能:

@装饰器名
def 目标装饰函数名():
  pass
#上面的效果是 目标装饰函数名=装饰器(目标装饰函数名)

所以在需要替换原函数的时候,可以在目标装饰函数定义的上一行加上@装饰器名

所以上面的代码会变成:

def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper
@timmer2
def test7():
  print("test7")
@timmer2
def test6(x):
  print(x)
test7()
test6(2)
import time
def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    return res
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper
@timmer2
def test4():
  print("test4 run")
  return "test4 done"
test4()
print("--------")
print(test4())

第二个补充:

可以一个函数,可以使用多个装饰器

比如:

@装饰器1

@装饰器2

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
初学python数组的处理代码
Jan 04 Python
精确查找PHP WEBSHELL木马的方法(1)
Apr 12 Python
Python cookbook(数据结构与算法)找到最大或最小的N个元素实现方法示例
Feb 13 Python
python实现requests发送/上传多个文件的示例
Jun 04 Python
python 创建一个空dataframe 然后添加行数据的实例
Jun 07 Python
python3解析库pyquery的深入讲解
Jun 26 Python
解决pyinstaller打包pyqt5的问题
Jan 08 Python
int在python中的含义以及用法
Jun 27 Python
Python考拉兹猜想输出序列代码实践
Jul 05 Python
python实现在函数中修改变量值的方法
Jul 16 Python
ubuntu 安装pyqt5和卸载pyQt5的方法
Mar 24 Python
Python爬虫分析微博热搜关键词的实现代码
Feb 22 Python
python保留小数位的三种实现方法
Jan 07 #Python
pytorch之ImageFolder使用详解
Jan 06 #Python
pytorch之inception_v3的实现案例
Jan 06 #Python
pytorch之添加BN的实现
Jan 06 #Python
PyTorch学习:动态图和静态图的例子
Jan 06 #Python
pytorch动态网络以及权重共享实例
Jan 06 #Python
selenium中get_cookies()和add_cookie()的用法详解
Jan 06 #Python
You might like
DC《小丑》11项提名领跑奥斯卡 Netflix成第92届奥斯卡提名最大赢家
2020/04/09 欧美动漫
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
PHP中Closure类的使用方法及详解
2015/10/09 PHP
Yii rules常用规则示例
2016/03/15 PHP
PHP自定义图片缩放函数实现等比例不失真缩放的方法
2016/08/19 PHP
PHP实现简单ajax Loading加载功能示例
2016/12/28 PHP
使用PHPMailer发送邮件实例
2017/02/15 PHP
PHP使用openssl扩展实现加解密方法示例
2020/02/20 PHP
javascript中的对象和数组的应用技巧
2007/01/07 Javascript
jQuery操作input type=radio的实现代码
2012/06/14 Javascript
高性能Javascript笔记 数据的存储与访问性能优化
2012/08/02 Javascript
吐槽一下我所了解的Node.js
2014/10/08 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
浅谈如何通过node.js对数据进行MD5加密
2018/05/16 Javascript
简单了解JS打开url的方法
2020/02/21 Javascript
JQuery实现折叠式菜单的详细代码
2020/06/03 jQuery
在vue中使用回调函数,this调用无效的解决
2020/08/11 Javascript
使用vue构建多页面应用的示例
2020/10/22 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
2021/01/05 Vue.js
python解析文件示例
2014/01/23 Python
在win和Linux系统中python命令行运行的不同
2016/07/03 Python
python模块导入的细节详解
2018/12/10 Python
利用Python查看微信共同好友功能的实现代码
2019/04/24 Python
Python PyInstaller库基本使用方法分析
2019/12/12 Python
python读取Kafka实例
2019/12/23 Python
Python爬虫实现vip电影下载的示例代码
2020/04/20 Python
如何使用Python自动生成报表并以邮件发送
2020/10/15 Python
基于第一个PhoneGap(cordova)的应用详解
2013/05/03 HTML / CSS
加拿大的标志性百货公司:Hudson’s Bay(哈得逊湾)
2019/09/03 全球购物
J2EE中的容器都包括哪些
2013/08/21 面试题
酒店个人培训自我鉴定
2013/12/11 职场文书
大学自我鉴定
2013/12/20 职场文书
财务总监管理岗位职责
2014/03/08 职场文书
毕业设计致谢语
2015/05/14 职场文书
python turtle绘制多边形和跳跃和改变速度特效
2022/03/16 Python
星际争霸:毕姥爷vs解冻03
2022/04/01 星际争霸