ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python里的装饰器

2020-02-06 20:07:14  阅读:341  来源: 互联网

标签:函数 Python 叔叔 uncle neighbor 装饰 wang


装饰器

装饰器是干什么用的?
装饰器可以在不修改某个函数的情况下,给函数添加功能。
形象点来说,从前有一个王叔叔,他一个人住在家里,每天打扫家,看书。于是定义如下一个函数:

def uncle_wang():
    sweeping()
    reading()

后来呢,有一天,大头儿子一家搬到了王叔叔隔壁 :-D 。根据剧情,一天,大头儿子的妈妈请王叔叔来家里吃饭,那么,王叔叔的日程就添加了“去隔壁吃饭”这一项,但是又不能修改王叔叔之前的日程,怎么实现?这时,就可以给王叔叔添加一个装饰器,给这个装饰器起个名字,姑且就叫neighbor,然后就写成这样:

@neighbor
def uncle_wang():
    sweeping()
    reading()

然后王叔叔去大头儿子家吃饭就提上日程啦,哈哈。(只是吃饭哦,不要想多了(⊙v⊙))
这个neighbor其实也是个函数,参数就是uncle_wang(没错,可以把函数名当成参数传来传去,还能当做返回值),在装饰器里面实现“去隔壁吃饭”:

def neighbor(func):
    eat_next_door()     # 自定义函数,去隔壁吃饭
    return func         # 原来的函数不变,直接返回

最后是执行,直接运行uncle_wang()即可

# 执行函数
uncle_wang()    # 相当于不加装饰器,直接执行 neighbor(uncle_wang)()

这感觉就像是用neighbor装饰了uncle_wang,丰富了王叔叔的生活,从此变成了隔壁老王。实现方式就是套娃,给uncle_wang套个neighbor,变成neighbor(uncle_wang)(这整个东西是个函数名),然后调用这个函数: neighbor(uncle_wang)(),形如:函数名()
在Python里,这个套娃的操作简化成了装饰器,直接在原函数上面添加@neighbor,然后调用的时候还是写成uncle_wang(),但是这个装饰过的王叔叔已经不是原来的王叔叔了,他现在其实是隔壁老王。

王叔叔的新日程搞定了,但是还有个问题,就是顺序。现在的日程顺序相当于:

eat_next_door()
sweeping()
reading()

请人吃饭当然是吃晚饭啦,所以eat_next_door()需要排在最后面,而neighbor函数不能先返回(return func)然后才执行eat_next_door(),众所周知,函数返回了就结束了,后面的东西都不管了。
所以,继续套娃,再搞个函数进去,写成这样:

def neighbor(func):
    def wrapper():          # 套娃函数,注意这里是定义,不是执行
        func()              # 相当于不带装饰器的 uncle_wang()
        eat_next_door()     # 自定义函数,去隔壁吃饭
    return wrapper          # 直接返回套娃函数

这样顺序就对了,王叔叔很满意~
现在这个装饰器基本成型了,但是现在还不能处理原函数的参数和装饰器函数的参数,继续改进的实现方式可以去看廖雪峰老师的教程,写得很不错,我就是从那学来的。

(嗨,又水了一篇,之前还说要测一下手动实现和库函数实现的二分查找的耗时差距,正事还是放到下次吧……)

参考资料:

  1. 装饰器 - 廖雪峰的官方网站
  2. 隔壁老王的梗是怎么来的 - 知乎

标签:函数,Python,叔叔,uncle,neighbor,装饰,wang
来源: https://www.cnblogs.com/adjwang/p/12270094.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有