装饰器

2018-10-25 13:49:37

装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器。

一般函数操作(不用装饰器):

  1. import time
  2. print(time.time())
  3. def i_can_sleep():
  4. time.sleep(3)
  5. start = time.time()
  6. i_can_sleep()
  7. stop = time.time()
  8. print("函数运行了%s"%(stop - start))

执行结果:

使用装饰器:

  1. 下面程序分为4步走(外部函数、返回嵌套函数、嵌套函数+语法糖(@装饰函数简写)+被装饰函数+调用被装饰的函数);若有大量的调用函数i_can_sleep并查看程序运行了多长时间,我们就嘚不厌其烦的定义新的startstop变量,然后打印时间
  1. 为此,我们就需要更简单的方法,装饰器,把这些重复的工作封装到装饰函数中也就是封装到@装饰函数名(语法糖)
  1. 代码如下:
  1. ###################################
  2. import time
  3. def timer(fun):#参数是我们要传入的被装饰函数,记下面的i_can_sleep函数 #1
  4. #此处我们需要在函数内部再定义一个内部函数,即嵌套函数
  5. def decorator():
  6. start = time.time()
  7. fun() #调用被装饰的函数,下面的i_can_sleep()
  8. stop = time.time()
  9. print('被装饰的函数i_can_sleep程序执行时间为:',stop-start) #给被装饰函数添加计时器功能
  10. return decorator
  11. @timer #装饰函数 # 2
  12. def i_can_sleep():#我们要装饰的函数,即被装饰函数 # 3
  13. time.sleep(3)
  14. i_can_sleep() #最后一步调用程序 # 4
  15. # 其实上面的第四部也可以按下面写,只是装饰器简化下面的步骤。
  16. #next = timer(i_can_sleep);next()
  1.  

执行结果如下:

  1. 可以看到执行结果和不使用装饰器一样的。看上去使用装饰器复杂了,实际上,对于大量执行计时器操作,就不用重复定义变量并打印结果了,我们使用装饰器只需改变少量实参即可即可省去重复操作,因为我们把一部分重复操作封装在装饰函数中,@装饰函数名。
  2.  
  3. 带参数的被装饰函数上面是不带参数的装饰器,下面是带参数的装饰器,注意:1、参数放在内部函数中#12、被装饰的函数也要加上参数 看#2;定义被装饰的函数有参数看#3、#43、定义被装饰函数时(语法糖下面的函数是被装饰函数),形参名字和上面的嵌套函数可以不一致。
  1. print("---------------------------------------------------")
  2. # 带参数的装饰器
  3. def wai(func):
  4. def nei(a,b): #参数放在内部函数中 #1
  5. print('start')
  6. func(a,b) #被装饰函数调用也要加上参数 #2
  7. print('stop')
  8. return nei
  9. @wai
  10. def add(m,n): #加法 #3
  11. return print(m+n) #参数名和嵌套函数中的参数名字可以不同。
  12. add(,)
  13. # 可以多次使用语法糖调用装饰器
  14. @wai
  15. def sub(x,y): #减法 #4
  16. return print(x-y)
  17. sub(,)

执行结果如下:

带参数的装饰器(带参数的语法糖)

不改变内部被装饰函数,通过在语法糖(@装饰函数名)后面添加实参和并且在装饰函数再加一层外层函数

  1. def add_chars(argv):
  2. def wai(func):
  3. def nei(a,b):
  4. print('开始:%s'%argv)
  5. func(a,b)
  6. print('结束')
  7. return nei
  8. return wai
  9. @add_chars('加法') #语法糖名字要和多层嵌套函数最外层函数名一致,并且参数对应最外层函数形参
  10. def add(m,n):
  11. return print(m,'+',n,'=',m+n)
  12. add(4,6)
  13. @add_chars('减法') #
  14. def sub(x,y): #减法
  15. return print(x,'-',y,'=',x-y)
  16. sub(11,4)
  17. # 装饰器带参数;在语法糖上带参数
  18. # 可以看到一层嵌套函数,出入的参数满了,我们可以在最外面加一层嵌套函数
  1.  

执行结果如下:

  1.  
  2. 小白学习笔记,如有理解错误,望批评指正,大佬止步。

Python小白学习之函数装饰器的更多相关文章

  1. python语言中的函数装饰器

    装饰器 什么是装饰器? 装饰:给已有的对象(函数)添加新的功能 器:工具              在python中指具备某些功能的函数 装饰器:装饰器就是一个给其他函数增加功能的函数 一种设计原则: ...

  2. Python: 无参数的函数装饰器

    写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数的函数,它返回一个接收函数的的函数.但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函 ...

  3. Python带参数的函数装饰器

    # -*- coding: utf-8 -*- # author:baoshan # 带参数的函数装饰器 def say_hello(country): def wrapper(func): def ...

  4. 流畅的python第七章函数装饰器和闭包学习记录

    本章讨论的话题 python如何计算装饰器句法 python如何判断变量是不是局部的(通过函数内部是否给变量赋值过来判断是否是局部变量) 闭包存在的原因和工作原理(闭包是一种函数,它会保留定义函数时存 ...

  5. python之路(九)-函数装饰器

    装饰器 某公司的基础业务平台如下: def f1(): print('这是f1业务平台') def f2(): print('这是f2业务平台') def f3(): print('这是f3业务平台' ...

  6. python基础学习1-双层装饰器(实现登陆注册)

    LOGIN_USER = {"IsLogin":False} def check_login(func): #检查登陆的装饰器 def inner(*args,**kwargs): ...

  7. 【Python入门学习】闭包&装饰器&开放封闭原则

    1. 介绍闭包 闭包:如果在一个内部函数里,对在外部作用域的变量(不是全局作用域)进行引用,那边内部函数被称为闭包(closure) 例如:如果在一个内部函数里:func2()就是内部函数, 对在外部 ...

  8. python学习日记(函数--装饰器)

    楔子 前提,我有一段代码(一个函数). import time def run_time(): time.sleep(0.1) print('我曾踏足山巅') 需求1:现在,我想计算这段代码的运行时间 ...

  9. Python学习日记(九) 装饰器函数

    1.import time a.time.time() 获取到当前的时间,返回值为浮点型 import time print(time.time()) #1565422783.6497557 b.ti ...

随机推荐

  1. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  2. 大话Linux内核中锁机制之原子操作、自旋锁

    转至:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其 ...

  3. Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解

    在LINUX的时钟中断中涉及至二个全局变量一个是xtime,它是timeval数据结构变量,另一个则是jiffies,首先看timeval结构struct timeval{time_t tv_sec; ...

  4. Java中的IO流(六)

    上一篇<Java中的IO流(五)>把流中的打印流PrintStream,PrintWriter,序列流SequenceInputStream以及结合之前所记录的知识点完成了文件的切割与文件 ...

  5. iOS 利用KeyChain+ IDFV + BundleID 来作为UUID,保证传给服务端的UUID唯一

    查了相关资料,发现只有KeyChain + IDFV可以保证UUID唯一,参考以下代码 , UICKeyChainStore + (NSString*)identifierForVender{ UIC ...

  6. 有关集合的foreach循环里的add/remove

    转自:Hollis(微信号:hollischuang) 在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 1 .foreach循环 ...

  7. summernote富文本编辑器的使用

    最近在开发一个微信公众号的后台,微信公众号编辑的文章一直没有得到很好地适应,大多数人也是在其他的编辑软件中编辑好之后直接去复制到微信公众平台中,考虑到复制后会排版出现问题,所以给大家推荐一款很不错的W ...

  8. ionic ios 打包 真机测试常见问题

    1.ionic 项目在windows下正常打包安卓包时  迁移到mac下打包ios时  不需要复制平台目录platforms即可  不用再mac下去安装各种插件信息 2.ionic 下不能访问api信 ...

  9. 树莓派安装SimpleCV

    开源计算机视觉框架.python2 安装 (http://simplecv.readthedocs.io/en/latest/HOWTO-Install%20on%20RaspberryPi.html ...

  10. golang 防SQL注入 基于反射、TAG标记实现的不定参数检查器

    收到一个任务,所有http的handler要对入参检查,防止SQL注入.刚开始笨笨的,打算为所有的结构体写一个方法,后来统计了下,要写几十上百,随着业务增加,以后还会重复这个无脑力的机械劳作.想想就l ...