一、简介

装饰器是是修改其它函数功能的函数;其意义是让其他函数在不修改任何代码的前提下增加额外功能

二、数据类型

首先我们来看一段简单的代码:

  1. from types import MethodType,FunctionType
  2.  
  3. class A(object):
  4. def f1(self):
  5. pass
  6.  
  7. def f2(a, b):
  8. return a + b
  9.  
  10. if __name__ == '__main__':
  11. a = A()
  12. print(type(a.f1)) #<class 'method'>
  13. print(type(f2)) #<class 'function'>

结论:不难看出,f1的类型是方法,f2的类型是函数;那有人会问了解这个有啥作用呢?其实了解这个有助于我们下面了解装饰器的原理

三、认识装饰器:

let's go... 我们来看一个案例:

  1. def B():
  2. print("now you are inside the B() function")
  3.  
  4. def sing():
  5. return "now you are in the sing() function"
  6.  
  7. def eat():
  8. return "now you are in the eat() function"
  9.  
  10. def sleep():
  11. return "now you are in the sleep() function"
  12.  
  13. print(sing())
  14. print(eat())
  15. print(sleep())
  1. #输出的结果为:
  2. now you are inside the hi() function
  3. now you are in the sing() function
  4. now you are in the eat() function
  5. now you are in the sleep() function

结论:那现在我们知道了可以在函数中定义另外的函数。也就是说:我们可以创建嵌套的函数

我们再接着看一段代码,如何让函数作为参数传给另外一个函数的:

  1. def A():
  2. return "hi 小陈!"
  3.  
  4. def doSomethingBeforeA(func):
  5. print("I am doing some boring work before executing A()")
  6. print(func())
  7.  
  8. #执行:
  9. doSomethingBeforeA(A)
  1. #输出结果:
  2. I am doing some boring work before executing A()
  3. hi 小陈!

什么?你还没看懂,那我们再看一个案例:

  1. from types import FunctionType
  2.  
  3. def text():
  4. return "Hello world!"
  5.  
  6. def add_itali(func: FunctionType):
  7. def new_func():
  8. #print("now you are in the new_func() function")
  9. return text() #返回text()函数
  10. return new_func

  1. #执行:
  2. print(type(add_itali(text)))
  3. print(add_itali(text)())
  1. #输出结果:
  2. <class 'function'>
  3. Hello world

难么现在你看懂了么?如果还是没懂,没关系我们再来看看下一段代码:

  1. def new_decorator(func):
  2. def wrapTheFunction():
  3. print("I am doing some boring work before executing func()")
  4. func()
  5. print("I am doing some boring work after executing func()")
  6. return wrapTheFunction
  7.  
  8. def requiring_decoration():
  9. print("I am the function which needs decoration")

  1. #执行:
  2. requiring_decoration()
  3.  
  4. #输出结果:
  5. I am the function which needs decoration
  1. #执行:
  2. new_decorator(requiring_decoration)()
  3.  
  4. #输出结果:
  5. I am doing some boring work before executing func()
  6. I am the function which needs decoration
  7. I am doing some boring work after executing func()

有人会有疑问,new_decorator(requiring_decoration)()为哈后面要加“()”呢去,请继续往下看:

  1. #执行:
  2. print(new_decorator(requiring_decoration))
  3.  
  4. #输出结果:
  5. function new_decorator.<locals>.wrapTheFunction at 0x000001FC976BB620>

为什么会这样呢,请随我娓娓道来。。。

四、装饰器的优雅使用:

那么好,我们把上面代码再优化下,用装饰器常用的表达方式表示出来:

  1. def new_decorator(func):
  2. def wrapTheFunction():
  3. print("I am doing some boring work before executing func()")
  4. func() #被装饰的函数
  5. print("I am doing some boring work after executing func()")
  6. return wrapTheFunction
  7.  
  8. @new_decorator
  9. def requiring_decoration():
  10. print("I am the function which needs decoration")
  1. #执行:
  2. requiring_decoration()
  3.  
  4. #输出结果:
  5. I am doing some boring work before executing func()
  6. I am the function which needs decoration
  7. I am doing some boring work after executing func()

老铁们,现在你们懂了么,没懂我们再来看一段代码:

  1. #需求: <b><i> Hello World!</i></b>
  2. from types import FunctionType

  3. def add_bold(func: FunctionType):
  4. def new_func():
  5. return f"<b>{func()}</b>"
  6. return new_func
  7.  
  8. def add_itali(func: FunctionType):
  9. def new_func():
  10. return f"<i>{func()}</i>"
  11. return new_func
  12.  
  13. @add_itali # 语法
  14. @add_bold
  15. def text():
  16. return "Hello world!"
  1. #执行:
  2. print(text())
  3.  
  4. #输出结果:
  5. <i><b>Hello world!</b></i>

五、总结:

  1. #语法:装饰器就是一个函数
  2. def 装饰器名(func):
  3. def wrapper(*args, **kwargs):
  4. // 要做的装饰 ,,省略若干代码
  5. result = func(*args,**kwargs)
  6. return result
  7. return wrapper

python装饰器基础及应用的更多相关文章

  1. Python装饰器基础及运行时间

    一.装饰器基础 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数).装饰器可能会处理被装饰的函数,然后把他返回,或者将其替换成另一个函数或可调用对象. eg:decorate装饰器 @decor ...

  2. Python装饰器基础

    一.Python装饰器引入 讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切. 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个 ...

  3. Python基础(五) python装饰器使用

    这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表示调用了两次 ...

  4. Python开发基础-Day7-闭包函数和装饰器基础

    补充:全局变量声明及局部变量引用 python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 global关键字用来在函数或其 ...

  5. [python 基础]python装饰器(一)添加functools获取原函数信息以及functools.partial分析

    python装饰器学习的时候有两点需要注意一下 1,被装饰器装饰的函数取其func.__name__和func.func_doc的时候得到的不是被修饰函数的相关信息而是装饰器wrapper函数的doc ...

  6. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  7. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  8. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  9. (转载)Python装饰器学习

    转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...

随机推荐

  1. SAP S/4HANA 2020安装实录

    欢迎关注微信公众号:sap_gui (ERP咨询顾问之家) 今天开始试着安装SAP S/4HANA 2020版本,也是目前SAP ERP最高的版本,总安装文件大小大概50GB,数据库版本必须是HANA ...

  2. 使用sql导出数据_mysql

    在mysql中 使用sql 脚本导出数据的方式之一: select * from table_name where x=y  INFO OUTFILE "/tmp/table_name.tx ...

  3. Magicodes.IE 3.0重磅设计畅谈

    总体设计 Magicodes.IE导入导出通用库,支持Dto导入导出.模板导出.花式导出以及动态导出,支持Excel.Csv.Word.Pdf和Html. IE在去年年底重构一次之后,经过这么长时间的 ...

  4. 1.流程控制--if

    流程控制--if -*- coding:utf-8 -*- #定义字符编码 1.判断条件if age = input("输入年龄:") #将交互式输入内容赋值给age,默认内容为字 ...

  5. 【RabbitMQ-7】RabbitMQ—交换机标识符

    死信队列概念 死信队列(Dead Letter Exchange),死信交换器.当业务队列中的消息被拒绝或者过期或者超过队列的最大长度时,消息会被丢弃,但若是配置了死信队列,那么消息可以被重新发布到另 ...

  6. Pandas_VBA_数据筛选比较

    Pandas与VBA筛选数据的比较 Author:Collin_PXY 需求: 将B列里值为Completed 和 Pending的A,B,D三列数据筛选出来,新建一个名为 Filited_data的 ...

  7. 阅源-jdk8-FunctionalInterface注解

    package java.lang; import java.lang.annotation.*; /** * An informative annotation type used to indic ...

  8. 自定义泛型方法, 三级排序, low版,待升级

    package com.jd.dashboard.util; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken ...

  9. RocketMQ4.x安装部署

    1.下载安装包:https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.2.0/rocketmq-all-4.2.0-bin-release.zip ...

  10. 基于FFmpeg的Dxva2硬解码及Direct3D显示(一)

    目录 前言 名词解释 代码实现逻辑 前言 关于视频软解码的资料网上比较多了,但是关于硬解可供参考的资料非常之有限,虽然总得来说软解和硬解的基本逻辑一样,但是实现细节上的差别还是比较多的.虽然目前功能已 ...