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实现方法
Nov 18 Python
Python中使用PDB库调试程序
Apr 05 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
Jul 04 Python
python中将函数赋值给变量时需要注意的一些问题
Aug 18 Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
Dec 12 Python
python如何通过实例方法名字调用方法
Mar 21 Python
python对于requests的封装方法详解
Jan 03 Python
python实现学员管理系统
Feb 26 Python
tensorflow 只恢复部分模型参数的实例
Jan 06 Python
Tensorflow 卷积的梯度反向传播过程
Feb 10 Python
python 项目目录结构设置
Feb 14 Python
在 Python 中使用 7zip 备份文件的操作
Dec 11 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 rand()造成CPU 100%的解决办法
2010/05/18 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
PHP数据类型之整数类型、浮点数的介绍
2013/04/28 PHP
javascript replace()正则替换实现代码
2010/02/26 Javascript
javascript对数组的常用操作代码 数组方法总汇
2011/01/27 Javascript
Javascript绝句欣赏 一些经典的js代码
2012/02/22 Javascript
利用jquery写的左右轮播图特效
2014/02/12 Javascript
JS基于面向对象实现的选项卡效果示例
2016/12/20 Javascript
vue cli webpack中使用sass的方法
2018/02/24 Javascript
Vue.directive()的用法和实例详解
2018/03/04 Javascript
在angular 6中使用 less 的实例代码
2018/05/13 Javascript
Vue.js添加组件操作示例
2018/06/13 Javascript
详解vue如何使用rules对表单字段进行校验
2018/10/17 Javascript
layDate插件设置开始和结束时间
2018/11/15 Javascript
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
vue 组件之间事件触发($emit)与event Bus($on)的用法说明
2020/07/28 Javascript
学习python 之编写简单乘法运算题
2016/02/27 Python
浅谈终端直接执行py文件,不需要python命令
2017/01/23 Python
python通过elixir包操作mysql数据库实例代码
2018/01/31 Python
python 实现求解字符串集的最长公共前缀方法
2018/07/20 Python
Flask框架学习笔记之模板操作实例详解
2019/08/15 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
python3正则模块re的使用方法详解
2020/02/11 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
音频处理 windows10下python三方库librosa安装教程
2020/06/20 Python
python 通过exifread读取照片信息
2020/12/24 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
HTML5边玩边学(2)基础绘图实现方法
2010/09/21 HTML / CSS
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
几道数据库的面试题或笔试题
2014/05/31 面试题
cf战队收人广告词
2014/03/14 职场文书
委托书怎么写
2014/07/31 职场文书
自书遗嘱范文
2015/08/07 职场文书
2016年端午节红领巾广播稿
2015/12/18 职场文书
2019预备党员转正申请书模板2篇!
2019/08/07 职场文书
uniapp开发打包多端应用完整方法指南
2022/12/24 Javascript