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基础教程之类class定义使用方法
Feb 20 Python
理解Python垃圾回收机制
Feb 12 Python
详谈Python高阶函数与函数装饰器(推荐)
Sep 30 Python
Python 中的lambda函数介绍
Oct 10 Python
Python多进程fork()函数详解
Feb 22 Python
详解Pandas之容易让人混淆的行选择和列选择
Jul 10 Python
pytorch实现用Resnet提取特征并保存为txt文件的方法
Aug 20 Python
python字符串替换re.sub()方法解析
Sep 18 Python
Python脚本操作Excel实现批量替换功能
Nov 20 Python
Python requests上传文件实现步骤
Sep 15 Python
python基于exchange函数发送邮件过程详解
Nov 06 Python
Python开发五子棋小游戏
May 02 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(一)
2006/10/09 PHP
PHP数组实例总结与说明
2011/08/23 PHP
ThinkPHP的URL重写问题
2014/06/22 PHP
10个对初学者非常有用的PHP技巧
2016/04/06 PHP
Zend Framework入门教程之Zend_View组件用法示例
2016/12/09 PHP
jQuery方法简洁实现隔行换色及toggleClass的使用
2013/03/15 Javascript
JavaScript DOM元素尺寸和位置
2015/04/13 Javascript
jQuery实现可编辑的表格实例讲解(2)
2015/09/17 Javascript
Bootstrap每天必学之导航条
2015/11/27 Javascript
深入剖析JavaScript中的函数currying柯里化
2016/04/29 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
jQuery UI插件实现百度提词器效果
2016/11/21 Javascript
vue axios用法教程详解
2017/07/23 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
JavaScript判断对象和数组的两种方法
2019/05/31 Javascript
微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)
2019/09/19 Javascript
JQuery Ajax如何实现注册检测用户名
2020/09/25 jQuery
jQuery实现增删改查
2020/12/22 jQuery
Python continue语句用法实例
2014/03/11 Python
Python标准库与第三方库详解
2014/07/22 Python
Python中turtle作图示例
2017/11/15 Python
Django项目开发中cookies和session的常用操作分析
2018/07/03 Python
美国开幕式潮店:Opening Ceremony
2018/02/10 全球购物
Yahoo-PHP面试题3
2012/01/14 面试题
JAVA软件工程师测试题
2014/07/25 面试题
干部选拔任用方案
2014/05/26 职场文书
防灾减灾标语
2014/10/07 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
2014年政风行风工作总结
2014/11/22 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
小学美术教学反思
2016/02/17 职场文书
MySQL 常见的数据表设计误区汇总
2021/06/07 MySQL
JavaScript 对象创建的3种方法
2021/11/17 Javascript
tp5使用layui实现多个图片上传(带附件选择)的方法实例
2021/11/17 PHP
《巫师》是美食游戏?CDPR10月将推出《巫师》官方食谱
2022/04/03 其他游戏