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交换变量
Sep 06 Python
python中关于日期时间处理的问答集锦
Mar 08 Python
python类定义的讲解
Nov 01 Python
Python处理RSS、ATOM模块FEEDPARSER介绍
Feb 18 Python
python3 requests中使用ip代理池随机生成ip的实例
May 07 Python
Python发送邮件功能示例【使用QQ邮箱】
Dec 04 Python
python射线法判断检测点是否位于区域外接矩形内
Jun 28 Python
django获取from表单multiple-select的value和id的方法
Jul 19 Python
浅谈python 调用open()打开文件时路径出错的原因
Jun 05 Python
Python drop方法删除列之inplace参数实例
Jun 27 Python
基于Python和C++实现删除链表的节点
Jul 06 Python
python中数组和列表的简单实例
Mar 25 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+MySQL实现的简单投票系统实例
2016/02/24 PHP
详解WordPress中用于更新和获取用户选项数据的PHP函数
2016/03/08 PHP
PHP带节点操作的无限分类实现方法详解
2016/11/09 PHP
Nginx下ThinkPHP5的配置方法详解
2017/08/01 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
2020/02/27 PHP
IE6与IE7中,innerHTML获取param的区别
2009/03/15 Javascript
jQuery学习总结之元素的相对定位和选择器(持续更新)
2011/04/26 Javascript
js中indexof的用法详细解析
2013/12/24 Javascript
jQuery的DOM操作之删除节点示例
2014/01/03 Javascript
jQuery is()函数用法3例
2014/05/06 Javascript
Jquery之Bind方法参数传递与接收的三种方法
2014/06/24 Javascript
jquery实现翻动fadeIn显示的方法
2015/03/05 Javascript
JavaScript 事件绑定及深入
2015/04/13 Javascript
javascript获取select值的方法分析
2015/07/02 Javascript
BootStrap树状图显示功能
2016/11/24 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
2017/01/19 Javascript
jQuery中复合选择器简单用法示例
2018/03/31 jQuery
TypeScript中的方法重载详解
2019/04/12 Javascript
[06:24]DOTA2 2015国际邀请赛中国区预选赛第二日TOP10
2015/05/27 DOTA
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
使用Python中的线程进行网络编程的入门教程
2015/04/15 Python
python使用wxPython打开并播放wav文件的方法
2015/04/24 Python
python计算方程式根的方法
2015/05/07 Python
Python中字典的基础知识归纳小结
2015/08/19 Python
Python切片知识解析
2016/03/06 Python
python获取交互式ssh shell的方法
2019/02/14 Python
pytorch在fintune时将sequential中的层输出方法,以vgg为例
2019/08/20 Python
python连接PostgreSQL过程解析
2020/02/09 Python
TensorFlow的reshape操作 tf.reshape的实现
2020/04/19 Python
python3中for循环踩过的坑记录
2020/12/14 Python
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
高一军训的心得体会
2014/09/01 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书
网上祭英烈活动总结
2015/02/04 职场文书
试用期工作表现自我评价
2015/03/06 职场文书
mysql 索引的数据结构为什么要采用B+树
2022/04/26 MySQL