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数据结构之二叉树的统计与转换实例
Apr 29 Python
python 基础教程之Map使用方法
Jan 17 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
Feb 14 Python
Python matplotlib绘图可视化知识点整理(小结)
Mar 16 Python
python生成不重复随机数和对list乱序的解决方法
Apr 09 Python
pyqt5实现登录界面的模板
May 30 Python
Python迭代器模块itertools使用原理解析
Dec 11 Python
Django高并发负载均衡实现原理详解
Apr 04 Python
python3.5的包存放的具体路径
Aug 16 Python
Django怎么在admin后台注册数据库表
Nov 14 Python
浅谈Selenium+Webdriver 常用的元素定位方式
Jan 13 Python
解决pycharm 格式报错tabs和space不一致问题
Feb 26 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
PHP IPV6正则表达式验证代码
2010/02/16 PHP
php加密解密函数authcode的用法详细解析
2013/10/28 PHP
PHP迭代器实现斐波纳契数列的函数
2013/11/12 PHP
PHP IE中下载附件问题解决方法
2014/01/07 PHP
PHP中使用Session配合Javascript实现文件上传进度条功能
2014/10/15 PHP
PHP封装的数据库保存session功能类
2016/07/11 PHP
PHP基于curl post实现发送url及相关中文乱码问题解决方法
2017/11/25 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
2018/02/10 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
php libevent 功能与使用方法详解
2020/03/04 PHP
跨浏览器通用、可重用的选项卡tab切换js代码
2011/09/20 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
js换图片效果可进行定时操作
2014/06/09 Javascript
Node.js编码规范
2014/07/14 Javascript
jQuery中队列queue()函数的实例教程
2016/05/03 Javascript
jQuery弹出层插件popShow(改进版)用法示例
2017/01/23 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
让网站自动生成章节目录索引的多个js代码
2018/01/07 Javascript
JS实现的文件拖拽上传功能示例
2018/05/21 Javascript
Makefile/cmake/node-gyp中区分判断不同平台的方法
2018/12/18 Javascript
vue的keep-alive用法技巧
2019/08/15 Javascript
kafka调试中遇到Connection to node -1 could not be established. Broker may not be available.
2019/09/17 Javascript
Python的Flask站点中集成xhEditor文本编辑器的教程
2016/06/13 Python
浅谈python中的正则表达式(re模块)
2017/10/17 Python
Python 结巴分词实现关键词抽取分析
2017/10/21 Python
python多进程实现进程间通信实例
2017/11/24 Python
python Flask 装饰器顺序问题解决
2018/08/08 Python
python实现一组典型数据格式转换
2018/12/15 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
查看keras的默认backend实现方式
2020/06/19 Python
python pygame 愤怒的小鸟游戏示例代码
2021/02/25 Python
iframe与window.onload如何使用详解
2020/05/07 HTML / CSS
10条PHP编程习惯
2014/05/26 面试题
朝花夕拾读书笔记
2015/06/29 职场文书
Python中with上下文管理协议的作用及用法
2022/03/18 Python
Android存储中最基本的文件存储方式
2022/04/30 Java/Android