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. 一个简单的监控java进程获取日志的办法

    公司里面一个长时间运行的环境会出现问题, 这边简单写了一个脚本自动获取日志信息 脚本如下 注意 我的path 其实就是复用的 我们应用里面的jdk  剩下的就非常简单了. 每个日志都自动打包 并且移除 ...

  2. 不同信创服务器Redis7.0.5性能表现总结

    不同信创服务器Redis7.0.5性能表现总结 背景以及基础约定 随着美帝2022.10收紧EAR规定的硬件出口规定 信创事业迎来了一波新的高潮. 最近不仅仅要求国产化的硬件. 更要求国产化的OS,以 ...

  3. 基于eBPF的微服务网络安全(Cilium 1)

    基于eBPF的微服务网络安全 翻译自:Network security for microservices with eBPF 一些开源的kubernetes工具已经开始使用eBPF,这些工具大多数与 ...

  4. 【图论,网络流】CF1525F Goblins And Gnomes

    Problem Link 你在打怪.你有一个 \(n\) 个点 \(m\) 条边的 DAG,接下来会有 \(k\) 波怪来袭,第 \(i\) 波怪有 \(i\) 个,它们会各自选择走一条路径,要求它们 ...

  5. Promise的异常穿透和中断Promise的链式请求

    1.Promise的异常穿透 1==>当你使用Promise的then,进行链式调用的时候,可以在最后指定失败的回调 2==>前面任何操作出现了异常,都会传递到最后失败的回调中进行处理: ...

  6. linux root用户密码输入正确还是提示access denied

    问题:之前用远程工具连接一直都是好的,第二天上班找开远程工具要输root的密码了,输入用户密码后还是无效,可以确定用户密码是对的,其中有一个远程工具一直是连着的就没有问题. 排查问题: 1.相接用pa ...

  7. linux时间和当前时间相关8小时问题

    依次执行如下的代码: 1.更改时区 cp /usr/share/zoneinfo/GMT /etc/localtime ln -sf /usr/share/zoneinfo/Asia/Shanghai ...

  8. Docker 安装 Nacos 注册中心

    废话不多说直接上安装脚本: 在运行安装脚本之前,首先,我们查看一下 Nacos 的版本分别有哪些使用 docker search nacos: 然后在执行: docker pull nacos/nac ...

  9. 因为命名被diss无数次。简单聊聊编程最头疼的事情之一:命名

    本文已经收录进我的 80K+ Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide (「Java学习+面试指南」一份涵盖 ...

  10. Midjourney|文心一格prompt教程[Text Prompt(下篇)]:游戏、实物、人物、风景、动漫、邮票、海报等生成,终极模板教学

    Midjourney|文心一格prompt教程[Text Prompt(下篇)]:游戏.实物.人物.风景.动漫.邮票.海报等生成,终极模板教学 场景6:游戏 Prompt 真的越长越好吗? 按照 Mi ...