装饰器

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

def uncle_wang():
sweeping()
reading()

后来呢,有一天,大头儿子一家搬到了王叔叔隔壁 。根据剧情,一天,大头儿子的妈妈请王叔叔来家里吃饭,那么,王叔叔的日程就添加了“去隔壁吃饭”这一项,但是又不能修改王叔叔之前的日程,怎么实现?这时,就可以给王叔叔添加一个装饰器,给这个装饰器起个名字,姑且就叫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 # 直接返回套娃函数

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

附上完整代码:

# !/usr/bin/env python3
# -*- coding: utf-8 -*- def sweeping():
print('sweeping') def reading():
print('reading') def eat_next_door():
print('eat_next_door') def neighbor(func):
def wrapper(): # 套娃函数,注意这里是定义,不是执行
func() # 相当于不带装饰器的 uncle_wang()
eat_next_door() # 自定义函数,去隔壁吃饭
return wrapper # 直接返回套娃函数 @neighbor
def uncle_wang():
sweeping()
reading() if __name__ == "__main__":
uncle_wang()

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

参考资料:

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

Python里的装饰器的更多相关文章

  1. 对python里的装饰器

    内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效. 再回到我们的主 ...

  2. python高级之装饰器

    python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之 ...

  3. 第二篇:python高级之装饰器

    python高级之装饰器   python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函 ...

  4. Day11 Python基础之装饰器(高级函数)(九)

    在python中,装饰器.生成器和迭代器是特别重要的高级函数   https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...

  5. 【Python】【装饰器】

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  6. Python 语法糖装饰器的应用

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  7. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  8. python 多个装饰器的调用顺序

    python 多个装饰器的调用顺序 一般情况下,在函数中可以使用一个装饰器,但是有时也会有两个或两个以上的装饰器.多个装饰器装饰的顺序是从里到外(就近原则),而调用的顺序是从外到里(就远原则). 原代 ...

  9. python函数闭包-装饰器-03

    可调用对象 callable()  # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即  callable(对象)  返回为  True  的对象 x = 1 print(cal ...

随机推荐

  1. K:缓存数据库双写数据一致性方案

    对于缓存和数据库双写,其存在着数据一致性的问题.对于数据一致性要求较高的业务场景,我们通常会选择使用分布式事务(2pc.paxos等)来保证缓存与数据库之间的数据强一致性,但分布式事务的复杂性与对资源 ...

  2. OPEN GL

    https://blog.csdn.net/cdut100/article/details/45753227 https://www.jianshu.com/p/d22cf555de47 https: ...

  3. ELK学习实验008:Kibana的介绍

    一 简介 Kiana是一款开源的数据分析和可视化平台,它是 Elastic Stack成员之一,设计用于和 Elasticsearch协作.您可以使用 Kiana对 Elasticsearch索引中的 ...

  4. DEVOPS技术实践_12:创建持续集成的管道

    持续集成不仅包含了Jenkins或者相关其它的CI工具,也包含了包含代码如何控制,采用的什么分支策略等.不同的组织可能采用不同的类型的策略来完成CI,策略类型和项目的类型的有很大的关系. 一 分支策略 ...

  5. Google Vision OCR

    Google Vision OCR 爬坑建议 首先安装 Google Vision shell composer require google/cloud-vision 第一次使用的时候真的遇到的问题 ...

  6. CEF编译遇到的问题记录

    在使用vs2015编译cef官方代码的时候遇到很奇怪的问题, 我用官方的demo cefsimple例子程序编译debug版本 可以正常编译打开网页 正常的打开 我把官方的例子单独创建一个新的项目编译 ...

  7. AutoCad 二次开发 Jig操作之墙块的拖动

    测试结果: 主要思路:选择一段多段线,使用封装的jig类进行实时拖动,其原理就是在拖动的时候,确定被拖动的边,我是选择离输入第一个点最近的边作为拖动边,有了这条边,就能确定需要实时更改的点了,然后当鼠 ...

  8. Linux学习之路--常用命令

    #ls  显示文件信息 #ll  显示文件(不包括隐藏文件)具体信息 等于 #ls -l #ll -a 显示所有文件(包括隐藏文件)具体信息 #ll -htr aa  显示最近修改的文件 h是易读的 ...

  9. vue项目准备工作

    1.写文档: 产品说明.工作日志.接口说明文档.数据库说明文档.项目架构说明文档等···· 例如:后台管理系统:商品的管理.店铺的管理.店铺类别管理.管理员的管理.用户管理等·····    前端渲染 ...

  10. 网络爬虫简单介绍(python)

    一.简介 爬虫就是利用代码大量的将网页前端代码下载下来使用的一种程序,一般来说常见的目的为下: 1.商业分析使用:很多大数据公司都会从利用爬虫来进行数据分析与处理,比如说要了解广州当地二手房的均价走势 ...