最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

天天日报丨【Python语法糖】闭包和装饰器

来源:博客园

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 func1if __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中的一种语法糖,用于修饰一个函数,使其具有额外的某些功能

@func1def func():print("aaa")#不影响原有面数的功能,还能添加新的功能

模板

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

def func1(func) :    ...    def func2():        ...    return func    return func2@func1def 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()@func1def 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@func1def mysum(a, b):print(a + b)    if __name__ == "__main__":    mysum(1,2)

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

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

关键词: 局部变量 内部函数 过程分析