Python装饰器

装饰器是什么东西呢?就是起到装饰作用的这么一个函数,那这玩意有啥用呢?很多人都会抛出这样的疑问,咱们就通俗的说一下这个装饰器到底是什么东西,是什么工作原理呢?

什么是装饰器?

首先,装饰顾名思义就是装饰用,为什么需要对函数装饰呢?是因为要遵循一个“开放”--“封闭”原则,因为已经写好的函数可能已经经过很久的测试和应用,没有出现任何问题的函数体,如果对函数内部进行修改势必会造成一些意外的问题,另外,这个函数很有可能不是你自己写的,那么对函数内部结构不熟悉,变量的不熟悉等等也可能导致函数的运行出现问题。那么装饰器就起到了不改变原函数的功能和不改动原函数内部代码的前提下,给函数添加功能的作用。

就如同一个面包,想要增加奶油或果糖,如果抛开面包加入到面包中,不单单影响美观,还破坏了面包本身。那么在面包外层涂上奶油或果糖等等,不仅能达到想要的效果,还不会破坏面包本身。。这就是装饰器。

装饰器的基本形式

一般情况下,我们可以在要增加功能的函数前加上另外一个函数,来达到目的。

例如:

 1 def func_new():
 2     print('这里是func_new函数的输出。')
 3     func()                     #在函数内部调用原函数
 4     print('调用完毕')
 5
 6 def func():
 7     print('这里是原函func数的输出')
 8
 9 func_new()

#输出结果:
>>>这里是func_new函数的输出。
>>>这里是原函func数的输出
>>>调用完毕

虽然起到了装饰作用,也没有改变原函数内部,但我们在调用的时候却改变了调用的函数名。这在日常工作中是不可以的,因为原来的函数可能被很多部门或很多程序调用,那么如果为了增加函数的功能却改变其他程序或部门的调用那简直就是灾难。

如何让函数的调用依旧是原来的调用方式不改变,然后对这个函数增加功能呢?

让我们在执行原函数前执行其他函数,并且在函数没有被调用时不执行其他函数的调用。

如果:func = funcnew(func) 看似可以使用func()来调用原函数,但是,funcnew(func)在赋值给func变量之前就已经被执行了。这样是不对的。那么如何让func_new(func)赋值前不执行呢? 这里就用到了嵌套函数

def func_new(func):def inner():        #嵌套一个函数innerprint('这里是func_new函数的输出。')func()                     #在函数内部调用原函数print('调用完毕')return inner        #返回inner的内存地址。  (不要加括号哦,加了括号就是执行了。失去这个嵌套函数的意义了.)

这样做一个嵌套,那么当 func = funcnew(func) 时 funcnew(func) 不会被执行,而是返回了一个函数内存地址,这是因为func_new虽然被执行了。但返回的是inner,而inner没有被执行而返回的是inner的内存地址,所以,func得到的是一个函数内存地址。

func = func_new(func)   #这时变量func得到的是内存地址,func_new()函数没有执行。
func()          #与原函数名一致,执行后是修饰过的结果。

这时,函数装饰器的原理就搞定了。那么说,如果每次给函数添加装饰器都要做赋值操作,这样太麻烦了。。。是的,python调用装饰器时用@。使用装饰器时,在要装饰的函数上方,加上@装饰器函数名。------看代码。

@func_new    #调用装饰器函数
def func():print('这里是原函func数的输出')func()  #执行函数,功能实现。

是不是明白了一些呢?让我们把装饰器基本型列出来,从头再来看一下。。

装饰器基本型:
def decorator():      #这里是装饰器参数,装饰器也可以带入参数,函数调用装饰器时如果是带有参数的装饰器需要@decorator(参数)def outer(func):   #这里的func是需要装饰的函数名,使用@调用装饰器时,函数名会被自动带入。def inner(*args,**kwargs): #非固定参数是被调用函数的参数。''' 这里是需要装饰的内容'''return func(*args,**kwargs)      #在装饰内容执行完毕后,执行原函数。return innerreturn outer

让我们引用一个简单的小实例来看看装饰器如何使用。

 1 # 这是一个记录程序运行时间的小程序,用装饰器来对执行进行认证,并由装饰器来记录每个函数执后所需的时间。
 2 import time
 3
 4 pwd = '123'
 5 swith = False
 6 def login(func):    #实现认证执行的装饰器
 7     def inner(*args,**kwargs):   #为了能使函数调用到参数,不管套用了多少层的装饰器,都需要加入非固定参数
 8         global swith
 9         if not swith:
10             n = input('>>>')
11             if n == pwd:
12                 swith = True
13                 return func(*args,**kwargs)
14             else:
15                 return
16         else:
17             return func(*args,**kwargs)
18     return inner
19
20
21 def sum_t(func):    #记录程序执行时间的装饰器
22     def inner(*args,**kwargs):  #接受函数的参数
23         start = time.time()
24         f = func(*args,**kwargs)
25         end = time.time()
26         print(end - start)
27         return f   #返回函数返回值
28     return inner     #装饰器中的功能一定要包含调用装饰器函数的所有功能。否则得不到正确返回值或出错!
29
30 #三种不同形式的函数
31 @login      #先调用 认证装饰器,认证通过后执行函数功能。
32 @sum_t      #通过认证后,调用时间记录装饰器
33 def f1():      #不带参数和返回值的函数
34     time.sleep(2)
35     print('F1')
36
37 @login
38 @sum_t
39 def f2(a):       #带参数的函数。
40     time.sleep(2)
41     print('F2',a)
42
43 @login
44 @sum_t
45 def f3():   #带return 返回值的函数
46     time.sleep(2)
47     print('F3')
48     return '结束'   #函数中,如果有返回值在装饰器中也需要相应的加入对应的返回项
49
50 if __name__ == '__main__':
51     f1()
52     f2('OK')
53     f = f3()
54     print(f)

#执行结果:
>>>123          #输入密码通过后,依次执行。
F1
2.0004823207855225
F2 'ok'
2.0012047290802
F3
2.000471353530884'结束'

转载于:https://www.cnblogs.com/sly27/p/8707191.html

Python装饰器的原理与应用相关推荐

  1. python装饰器原理-python装饰器的原理和使用

    一.最简单的装饰器 装饰器是python中很基础也很实用的一个特性.通过装饰器我们可以很方便地为一些函数添加相同的功能.我们以测量函数运行时间为例来讲一讲python装饰器的运行原理. 1.使用装饰器 ...

  2. python 装饰器(Decorators)原理说明

    本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是, 在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我 ...

  3. python装饰器原理-Python 装饰器工作原理解析

    #!/usr/bin/env python #coding:utf-8 """ 装饰器实例拆解 """ def login00(func): ...

  4. Python 装饰器工作原理解析

    #!/usr/bin/env python #coding:utf-8""" 装饰器实例拆解 """def login00(func):pr ...

  5. python装饰器原理-深刻理解python装饰器

    我们要完全理解python装饰器,不是很容易,主要归结有如下困难: 1. 关于函数"变量"(或"变量"函数)的理解 2. 关于高阶函数的理解 3. 关于嵌套函数 ...

  6. 装饰器python3菜鸟教程_认识Python装饰器

    Python中的装饰器用来给Python中的函数添加一些辅助功能.比如我们可以把[输出日志]这个辅助功能写到一个装饰器里.只要我们在某个函数A之前添加了这个[输出日志]的装饰器,那么执行函数A的时候, ...

  7. python装饰器原理-看完这篇文章还不懂Python装饰器?

    原标题:看完这篇文章还不懂Python装饰器? 1.必备 2.需求来了 初创公司有N个业务部门,1个基础平台部门,基础平台负责提供底层的功能,如:数据库操作.redis调用.监控API等功能.业务部门 ...

  8. python装饰器原理-Python装饰器原理与用法分析

    这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念.原理.使用方法及相关操作注意事项,需要的朋友可以参考下 本文实例讲述了Python装饰器原理与用法.分享给大 ...

  9. python装饰器原理-python 中的装饰器及其原理

    装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...

  10. python装饰器原理-简单了解python装饰器原理及使用方法

    这篇文章主要介绍了简单了解python装饰器原理及使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 如果你接触 Python 有一段时间了的话 ...

最新文章

  1. 用人铁律:高层看胸怀、中层看德行、基层看才能
  2. 软件测试2019:第四次作业
  3. 使用Atomikos Transactions Essentials实现多数据源JTA分布式事务--转载
  4. 利用nf_conntrack机制存储路由,省去每包路由查找
  5. 论文推荐 | 2018中国卫星导航年会论文集
  6. ThinkPHP3.1快速入门(4)连贯操作
  7. dubbo源码解析-zookeeper创建节点
  8. 打开黑色_垃圾桶里的黑色塑料袋,打开一看,倒吸一口气!
  9. C#基于websocket-sharp实现简易httpserver(封装)
  10. 为什么 Deno 没有众望所归?超越 Node.js 还要做些什么?
  11. 【知识图谱】史上最全《知识图谱》2020综述论文,18位作者, 130页pdf
  12. Linux BT下载(7)-种子解析模块设计与实现1
  13. php 获取搜索引擎,php获取搜索引擎关键字来源(支持百度、谷歌等搜索引擎)的函数...
  14. 一个大二前端的2017自我总结
  15. Qt入门学习之Qt全局定义
  16. WARNING: A newer version of conda exists
  17. 如何增强大脑记忆力?提高大脑记忆能力的20个方法
  18. 从魅族的成功总结的几条经验?
  19. LLMs之Alpaca:《Alpaca: A Strong, Replicable Instruction-Following Model》翻译与解读
  20. CSS中实现div元素水平垂直居中

热门文章

  1. 【渝粤教育】电大中专品牌管理与推广 (2)_1作业 题库
  2. Python基础:字典(dict)与集合(set)
  3. 教你如何修改运行中的docker容器的端口映射
  4. 接口测试工具——postman
  5. 2018-2019-1 20165212 《信息安全系统设计基础》第八周学习总结(pwd)
  6. Java面向对象之多态(向上、向下转型) 入门实例
  7. 判断app访问还是web访问网站
  8. spring集成mybatis后怎么在控制台打印sql语句
  9. Liunx服务管理(Centos)
  10. 我是如何用redis做实时订阅推送的