一、闭包函数的概述

闭包 closure, 是一种代码的组织结构。当一个内嵌函数引用其外部作用域的变量,就形成一个闭包函数。闭包函数有一个内嵌函数,内嵌函数引用外部函数中的变量,外部函数的返回值是内嵌函数。

闭包是函数和所引用环境变量的组合体。闭包让函数持有状态,延长环境变量的生命周期。类似类里的类变量,可以用函数或类的__call__方法实现装饰器。闭包函数只是绑定自由变量,并不会立即执行。只有当闭包函数执行时,才会访问所引用的目标对象。

闭包函数加载的时候会访问闭包函数外部的代码,再次调用闭包函数的返回时执行闭包函数内部的代码。比如闭包函数的延迟绑定,闭包函数嵌套的匿名函数在外部函数访问时不会触发,会当作整体传递出去,只有再次调用才会触发函数体的执行。

优点是具备封装性,可实现隐式上下文管理,并减少参数,在设计上可替代部分全局变量,或将环境与调用接口分离。

缺点是对自由变量隐式依赖,会提升代码的复杂度。自由变量的生命周期变长,会提升内存的占用。

二、装饰器的概述

我们需要遵守开放封闭原则。

开放封闭原则:程序上线以后就应该对修改封闭,对扩展开放

修改封闭:不能修改功能性函数的源代码,不能修改功能性函数的调用方式

扩展开放:可以为原有的功能添加新功能

三、使用闭包函数完成装饰器的逐步实现

首先,我们定义一个函数

importtime, randomdefmsg():print('I have something to tell you, please wait a moment.')

time.sleep(random.randint(1, 5))print('I like you.')

msg()

该函数会随机休眠1-5秒钟。

现在,我们想要给该函数增加一个计时的功能,看看函数具体运行了多久。

importtime, randomdefmsg():print('I have something to tell you, please wait a moment.')

time.sleep(random.randint(1, 5))print('I like you.')

start_time=time.time()

msg()

stop_time=time.time()print('Run time is %s' % (stop_time - start_time))

并且如果要重复使用计时功能,就要写重复代码,所以我们想到了将计时功能封装成一个函数

defwrapper():

start=time.time()

msg()

stop=time.time()print('Run time is %s' % (stop -start))

wrapper()

我们将wrapper函数写死了,只能对内部调用的msg函数进行计时,使用闭包函数

deftimmer(func):defwrapper():

start=time.time()

func()

stop=time.time()print('Run time is %s' % (stop -start))return wrapper #将wrapper函数的内存地址作为返回值返回。

msg = timmer(msg) #作为参数的msg是我们定义的msg函数的内存地址

#作为变量名的msg是指向wrapper函数的内存地址

msg() 此时我们这样写看似在调用msg函数,但实际上是调用了wrapper函数

这样子我们就实现了偷梁换柱,在外观上没有更改msg函数的调用方式。

当传入的函数有参数或者有返回值时

deftimmer(func):def wrapper(*args, **kwargs):

strat_time=time.time()

res= func(*args, **kwargs)

stop_time=time.time()returnresreturn wrapper

装饰器的使用方法:语法糖

importtime, randomdeftimmer(func):def wrapper(*args, **kwargs):

strat_time=time.time()

res= func(*args, **kwargs)

stop_time=time.time()returnresreturnwrapper

@timmerdefmsg():print('I have something to tell you, please wait a moment.')

time.sleep(random.randint(1, 5))print('I like you.')

msg()

含参装饰器,含参装饰器是一个三层的闭包函数

importtimedeftimemer(partment):deffunc(func_1):def wrapper(*args,**wkargs):if partment=='task1':

start=time.time()

func_1(*args, **wkargs)

stop=time.time()print("the task1 run time is :", stop -start)elif partment=='task2':

start=time.time()

func_1(*args, **wkargs)

stop=time.time()print("the task2 run time is :", stop -start)returnwrapperreturnfunc

@timemer(partment='task1')deftask1():

time.sleep(2)print("in the task1")

@timemer(partment='task2')deftask2():

time.sleep(2)print("in the task2")

task1()

task2()

类实现的含参装饰器

from functools import wraps

classdecorate:def __init__(self, name):

self.name=name    # 装饰器的参数def __call__(self, func):

@wraps(func)def deco(*args, **kwargs):if self.name == 'Admin':passelif self.name == 'Student':passelif self.name == 'Teacher':passreturn func(*args, **kwargs)return deco

@decarate('Admin')

python中msg函数_Python 中闭包函数和装饰器相关推荐

  1. python中闭包函数_Python的闭包问题(关于内嵌函数引用闭包函数的变量问题)

    一.闭包: 记得:闭包的特性就是:内嵌函数会保存它引用的外围函数的变量值. 闭包概念:在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数和被引用的变量等 ...

  2. python算法和数据结构_Python中的数据结构和算法

    python算法和数据结构 To 至 Leonardo da Vinci 达芬奇(Leonardo da Vinci) 介绍 (Introduction) The purpose of this ar ...

  3. python中定义数据结构_Python中的数据结构—简介

    python中定义数据结构 You have multiples algorithms, the steps of which require fetching the smallest value ...

  4. python中修饰器的优点和作用_Python入门基础教程之装饰器

    Python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...

  5. python关键字详解_Python 中的关键字with详解

    在 Python 2.5 中,with关键字被加入.它将常用的 try ... except ... finally ...模式很方便的被复用.看一个最经典的例子: with open('file.t ...

  6. python参数化建模 书_Python 中如何实现参数化测试?

    之前,我曾转过一个单元测试框架系列的文章,里面介绍了 unittest.nose/nose2 与 pytest 这三个最受人欢迎的 Python 测试框架. 本文想针对测试中一种很常见的测试场景,即参 ...

  7. 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

  8. Python 闭包、单个装饰器、多个装饰器、装饰器修饰类、应用场景

    1. 闭包 在 Python 中,函数也可以作为参数.我们可以执行下面的代码: def func(a, b):return a + bprint(func) 我们直接输出函数名,而没有加括号.输出结果 ...

  9. 如何使用python装饰器_Python学习之如何使用装饰器 @decorator

    建议大家在看这篇文章之前还是点击上面这篇文章看一下,先了解一下什么是装饰器之后再看. 猿人学python之我的学习笔记分享:如何使用装饰器 @decorator 上面代码中使用装饰器的方法看起来有点复 ...

  10. python内置哪些装饰器_Python内置的wraps装饰器有什么用

    Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...

最新文章

  1. pandas pickle序列化为二进制
  2. vim编辑环境设定[Linux]
  3. pdf批量添加图章_给PDF批量添加文本链接
  4. WEB前端 CSS(非布局)
  5. 排序算法比较以及代码展示
  6. 行测测评——矩阵、圆形、环形三角图形数列推理解题技巧
  7. BT5 WIFI破解
  8. 读书笔记:程序员的工具箱之“代码片段”
  9. win10 cmd窗口切换目录并运行python代码
  10. 一文看懂YOLO v3
  11. Java悲观锁Pessimistic-Lock常用实现场景
  12. GIT部署(三)GIT 远程仓库:添加远程库、从远程库克隆
  13. 651被远程计算机关闭,win7宽带连接提示错误651调制解调器报告了一个错误怎么办...
  14. 看linux centos版本信息,Linux CentOS查看操作系统版本信息
  15. 常用传感器讲解五--声音传感器-(KY-037)
  16. 南大通用GBase 8c斩获鲲鹏应用创新大赛2022全国总决赛金奖
  17. GowLom2 战神引擎传奇手游Mir200\Envir 目录主要配置文件中文翻译大全
  18. 算法课程设计:使用Python完成可视化的五子棋AI
  19. 监控系统中的服务器,监控系统中服务器的作用
  20. 「溪数科技」获逾5千万天使轮融资,开启智能运维加速模式!

热门文章

  1. 没了IDE,你的Java项目还能Run起来吗~
  2. 用了这么久的数据库连接池,你知道原理吗?
  3. 大神 20 年的专业数据分析心法全都在这里了
  4. 阿里技术专家:进击的 Java ,云原生时代的蜕变
  5. 在servlet中或者在filter中获取spring容器中的bean
  6. SpringBoot2.0基础案例分类总结,后续更新计划说明
  7. 深度-图像风格变换【二】
  8. 解决Div自适应高度的方法(转)
  9. Redis Cluster集群的搭建与实践[转]
  10. sqlMapConfig.xml配置文件详解