Python闭包和装饰器

参考:

https://zhuanlan.zhihu.com/p/453787908

https://www.bilibili.com/video/BV1JW411i7HR/?spm_id_from=333.337.search-card.all.click&vd_source=e44be2a53e5c6a4338b789d3833698fc

什么是闭包?

简单来说就是,在一个函数f1中又定义了一个函数f2,f2构成了闭包,一般来说f2会使用f1中的某些变量

def func():#外部函数
a = 1 #外部函数作用域里面的变量
print("this is func.")
def func1(num):#内部函数
print("this is func1")
print(num + a)
return func1 if __name__ == '__main__':
#func()#运行外部函数,内部面数就被创建了
var = func()#创建过程在funC国数的执行过程中
#var == funcl
var(3) #这样处理后,func的局部变量a会随着var一直存在于内存之中直到var被GC回收或用户删除

定义

维基百科的严肃定义:

在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。

解读一下就是:

  • 定义:闭包就是能够读取其外部函数变量的一个函数
  • 作用1:将外层函数(这个“外层”是相对于闭包函数来说的)内的局部变量和外层函数的外部连接起来的一座桥梁
  • 作用2:将外层函数的变量持久地保存在内存中

举例

再举一个例子认识闭包对于持久化局部变量的作用

mylist = [1,2,3,4,5]
def func(obj):
print('func:', obj)
def func1():
obj[0] += 1
print('func1:', obj)
return func1 if __name__ == '__main__':
var =func (mylist)
var()
#var: obj print( 'funcl: ' ,obj)
func:  [1,2,3,4,5]
func1: [2,2,3,4,5]
func1: [3,2,3,4,5]
func1: [4,2,3,4,5]
[Finished in 0.1s]

什么是装饰器?

装饰器是Python中的一种语法糖,用于修饰一个函数,使其具有额外的某些功能

@func1
def func():
print('aaa')
#不影响原有的功能,还能添加新的功能

模板

一般来说写一个装饰器的模板如下

def func1(func) :
...
def func2():
...
return func return func2 @func1
def xxx():
pass

装饰器使用过程分析

def func1(func):#外部闭包函数的参数是被装饰的对象
def func2():
print('aaabbb ')
return func()#返回了外部接收的被装饰面数的调用
return func2
#func1() takes 0 positional arguments but 1 was given #return func#返回了对象
#return func()#返回的是一个函数调用
#func1(myprint)()#接收被装饰的函数作为参数,而且还要继续调用一次
#func2() -> print('aaabbb') -> return myprint() @func1
def myprint():
print("你好,我是print") if __name__ == '__main__':
myprint()#func1(myprint)()

上述代码中,func1作为装饰器修饰函数myprint(),工作步骤如下:

​ ①调用func1函数,将myprint函数作为参数传入

​ ②调用func1的内部函数(闭包)func2,func2打印语句并使用了传入func1的参数myprint函数,将其作为返回值返回

​ ③结束

总结一下就是:整个过程中,我们多运行了一个闭包,这个闭包就是修饰器func1附加给myprint函数的功能

例子

1、含参数的装饰器
def arg_func(sex):
def func1(b_func) :
def func2():
if sex == 'man':
print("你不可以生娃")
if sex == 'woman':
print("你可以生娃")
return b_func()
return func2
return func1 #arg_func(sex= ' man ')()() --> func1#func1() --> func2
#func2() >('你不可以生娃') or print( '你可以生娃') b_func()
@arg_func(sex = 'man')
def man():
print("好好上班.")
@arg_func (sex = 'woman ')
def woman():
print("好好上班.") if __name__ == '__main__':
man ()
woman()

含参的装饰器需要再为装饰器函数再套一层来接受参数

2、被修饰函数带参数
def func1(func) :
def func2(x, y):
print(x, y)
x += 5
y += 5
return func(x, y) return func2 @func1
def mysum(a, b):
print(a + b) if __name__ == '__main__':
mysum(1,2)

被装饰的函数带参数:只需要在最内部函数传入参数即可

常用于某些数学模块的编写

【Python语法糖】闭包和装饰器的更多相关文章

  1. 彻底理解Python中的闭包和装饰器(下)

    上篇讲了Python中的闭包,本篇要讲的装饰器就是闭包的一个重要应用. 如果你还不知道什么是闭包,猛戳这里阅读:彻底理解Python中的闭包和装饰器(上) 什么是装饰器 装饰器的作用是在不修改函数定义 ...

  2. python中的闭包和装饰器

    重新学习完了函数,是时候将其中的一些重点重新捋一捋了,本次总结的东西只有闭包和装饰器 1.闭包 闭包是python函数中的一个比较重要功能,一般闭包都是用在装饰器上,一般学完闭包就会去学习装饰器,这俩 ...

  3. 21.python中的闭包和装饰器

    python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...

  4. Python 中的闭包与装饰器

    闭包(closure)是函数式编程的重要的语法结构.闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性. 如果在一个内嵌函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内嵌函数 ...

  5. python 小兵(8)闭包和装饰器

    闭包"是什么,以及,更重要的是,写"闭包"有什么用处. (个人理解) 1."闭包"是什么 首先给出闭包函数的必要条件: 闭包函数必须返回一个函数对象 ...

  6. 轻松理解python中的闭包和装饰器 (下)

    在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...

  7. 轻松理解python中的闭包和装饰器(上)

    继面向对象编程之后函数式编程逐渐火起来了,在python中也同样支持函数式编程,我们平时使用的map, reduce, filter等都是函数式编程的例子.在函数式编程中,函数也作为一个变量存在,对应 ...

  8. python基础16_闭包_装饰器

    不了解是否其他语言也有类似 python 装饰器这样的东西. 最近才发现ECMAScript6也是有生成器函数的,也有 yield  generator 装饰器的基础知识是闭包: # 闭包:嵌套函数, ...

  9. Python:Day16 闭包、装饰器

    def outer(): x = 10 def inner(): #条件一.inner就是一个内部函数 print(x) #条件二.引用外部作用域的一个变量,因为x在函数外部的,所以是外部作用域的变量 ...

  10. 聊聊Python中的闭包和装饰器

    1. 闭包 首先我们明确一下函数的引用,如下所示: def test1(): print("--- in test1 func----") # 调用函数 test1() # 引用函 ...

随机推荐

  1. [转帖]linux 系统级性能分析工具 perf 的介绍与使用

    目录 1. 背景知识 1.1 tracepoints 1.2 硬件特性之cache 2. 主要关注点 3. perf的使用 3.0 perf引入的overhead 3.1 perf list 3.2 ...

  2. [转帖]总结:Springboot监控Actuator相关

    一.介绍 由于项目中使用的仍然是比较老旧的1.5.6版本,所以本文是基于此版本进行描述. 二.Actuator使用 ActuatorActuator是Spring Boot提供的对应用系统的监控和管理 ...

  3. [转帖]线上Java 高CPU占用、高内存占用排查思路

    一.前言 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题.当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警.本文主要针对系统 ...

  4. Java单元测试浅析(JUnit+Mockito)

    作者:京东物流 秦彪 1. 什么是单元测试 (1)单元测试环节: 测试过程按照阶段划分分为:单元测试.集成测试.系统测试.验收测试等.相关含义如下: 1)       单元测试: 针对计算机程序模块进 ...

  5. 关于飞桨UIE等模型预测推理时间很久的问题分析以及解决,蒸馏剪枝部署问题解决

    1.关于飞桨UIE等模型预测推理时间很久的问题分析以及解决 1.1.原因分析 用uie做实体识别,Taskflow预测的时间与schema内的实体类别数量成正比,schema里面有多少个实体类别 实体 ...

  6. tomcat各版本与jdk及servlet各版本对应关系

    在项目部署的时候,如果对于Web应用没有选择正确的Web服务器版本,应用可能不能正常运行.下图为官方给的Servlet/JSP各规范与Web服务器Tomcat各版本的对应关系,如:支持Servlet ...

  7. MindSpore导入CUDA算子

    技术背景 当今众多的基于Python的AI框架(如MindSpore.PyTorch等)给了开发者非常便利的编程的条件,我们可以用Python的简单的语法写代码,然后由框架在后端自动编译成可以在GPU ...

  8. 9、数据库学习规划:Oracle - 学习规划系列文章

    甲骨文公司的Oracle数据库是笔者认为的目前市面上性能最强大的数据库.其版本也发展到了现在的12c,提供的功能也更加的强大了.以前笔者使用的是9i,十几年过去了,也才发展到12代,说明Oracle数 ...

  9. Leetcode刷题第一天-贪心

    455-分饼干 链接:455. 分发饼干 - 力扣(LeetCode) 优先使用最小饼干满足最小胃口,一个娃只能分一个饼干T_T不能加 1 class Solution: 2 def findCont ...

  10. P4747 [CERC2017] Intrinsic Interval 题解

    题目链接:Intrinsic Interval 讲讲析合树如何解决这种问题,其实这题很接近析合树的板题的应用. 增量法进行析合树建树时,需要用 ST 表预处理出 \(max\) 和 \(min\) 以 ...