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接收多播数据的代码
Mar 01 Python
python实现sublime3的less编译插件示例
Apr 27 Python
Python生成随机密码
Mar 10 Python
python3+dlib实现人脸识别和情绪分析
Apr 21 Python
Python 单元测试(unittest)的使用小结
Nov 14 Python
python实现的MySQL增删改查操作实例小结
Dec 19 Python
Python数据结构与算法(几种排序)小结
Jun 22 Python
python——全排列数的生成方式
Feb 26 Python
python3.6环境下安装freetype库和基本使用方法(推荐)
May 10 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
Jun 27 Python
Python使用sys.exc_info()方法获取异常信息
Jul 23 Python
Python 实现Mac 屏幕截图详解
Oct 05 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
Base64在线编码解码实现代码 演示与下载
2011/01/08 PHP
PHP转换IP地址到真实地址的方法详解
2013/06/09 PHP
php中define用法实例
2015/07/30 PHP
WordPress分页伪静态加html后缀
2016/06/08 PHP
php实现遍历文件夹的方法汇总
2017/03/02 PHP
在Laravel5.6中使用Swoole的协程数据库查询
2018/06/15 PHP
input 和 textarea 输入框最大文字限制的jquery插件
2011/10/27 Javascript
Prototype源码浅析 Enumerable部分(二)
2012/01/18 Javascript
css transform 3D幻灯片特效实现步骤解读
2013/03/27 Javascript
JQuery 图片滚动轮播示例代码
2014/03/24 Javascript
jQuery插件Tmpl的简单使用方法
2015/04/27 Javascript
jQuery插件实现多级联动菜单效果
2015/12/01 Javascript
Jquery实现纵向横向菜单
2016/01/24 Javascript
Angular2使用Angular-CLI快速搭建工程(二)
2017/05/21 Javascript
详解利用 Express 托管静态文件的方法
2017/09/18 Javascript
Angular.js通过自定义指令directive实现滑块滑动效果
2017/10/13 Javascript
Vue.directive()的用法和实例详解
2018/03/04 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
2018/07/04 Javascript
JavaScript实现飞舞的泡泡效果
2020/02/07 Javascript
python实现一个简单的ping工具方法
2019/01/31 Python
python3.6实现学生信息管理系统
2019/02/21 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
Django时区详解
2019/07/24 Python
python分布式编程实现过程解析
2019/11/08 Python
基于Pycharm加载多个项目过程图解
2020/01/19 Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
2020/08/07 Python
html5 input属性使用示例
2013/06/28 HTML / CSS
NBA德国官方网上商店:NBA Store德国
2018/04/13 全球购物
美国杰西潘尼官网:JCPenney
2019/06/12 全球购物
阿迪达斯新加坡官方网站:adidas新加坡
2019/12/06 全球购物
小学运动会表扬稿
2014/01/19 职场文书
煤矿开采专业求职信
2014/07/08 职场文书
项目负责人岗位职责
2015/02/15 职场文书
宝宝满月宴答谢词
2015/09/30 职场文书
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript