http://blog.sysuschool.com/u/mygod/index.html
请稍候,载入中。。。
 
请稍候,载入中。。。
2020-7-13 21:26:00
博文_python语言之闭包的应用_装饰器


继续闭包话题,留点心得体会。

 

前博文写了点关于闭包的理解,举了个直线函数的例子,可能你会说,可以设计line函数时,传3个参数不就可以了吗,即def line(x,a,b),这确实是可以实现类似的功能,说明下,举这个例子仅用来说明闭包,今天接着写点闭包的用法,装饰器就是经典的用法,甚至有人说,不懂装饰器,不能说自己懂python,哈哈

 

还有一个问题,上篇忘记说的,闭包有个缺点就是函数执行完,不能释放闭包中的变量,拿上篇的闭包来说明下:

 

# 传入参数a=10b=20,下面代码line01将指向函数lineline_conf函数内定义的那个函数),同时变量a=10b=20,一起形成一个闭包

line01=line_conf(10,20) 

# 下面执行line01,传入一个x100,将返回10*100+20

line01(100)

 

要说明的是,一般函数执行完成,局部变量立刻从内存中释放,但闭包不同,这里闭包含函数line、变量ab,执行line01时调用line函数执行,执行时调用闭包中的变量ab1020),执行完成后,变量ab将不能被释放,这是闭包的缺点,不能释放内存。

 

回归主题,装饰器是什么?看下面代码,这就是一个装饰器,函数名w1inner可自己随意,合法就行。

 

def w1(func):           # 定义一个函数,参数为引用函数,变量名func随意,这里意思是个函数

    def inner():           # 定义一个内部函数

                               # 功能代码

        func()                 # 执行引用函数

    return inner         # 返回内部函数

 

看结构是不是象闭包的写法,如果仔细看,你会发现不同之处在于,外面的函数传入的参数是一个函数,并且在内部函数中,执行了传入的函数!

 

这有什么用?举个简单例子:

 

# 定义一个函数say_hello,就一个功能,执行就打印一个字符串hello

def say_hello():

    print(“hello”)

 

现在我要实现不修改原函数的情况下,添加一个功能,再输出打印一个字符串byebye,看我用装饰器来做,就用上面那个装饰器,参考代码:

 

def w1(func):          

    def inner():          

        func()                

        print(“byebye”)        # 新增加的功能代码

    return inner        

 

# 下面代码,执行装饰器函数w1,将函数say_hello作为参数传入,返回给变量new_sayhello

new_sayhello = w1(say_hello)  

# 下面代码,执行new_sayhello,将看到输出hellobyebye

new_sayhello()

 

上面的代码可以在不修改原函数代码的情况下,给函数增加功能,具体怎么实现的,小结下:

 

执行w1(say_hello)new_sayhello应该得到一个返回的innerinner就是装饰器内的一个函数,注意new_sayhello这时仅指向这个函数定义,并没有执行,还有,根据闭包的说法,new_sayhello指向的函数inner,和外部函数w1传入的参数func一起构成一个闭包,对不对,如果没想明白,看看上篇闭包。

 

继续看下来,如果理解了闭包,就能理解下面这些(也许每个人的表述带偏见,看不明白的话可与我交流,这里主要是写给自己做个小结):

 

new_sayhello = w1(say_hello)  

这步执行后,new_sayhello指向了一个函数inner,附带一个参数func,一起构成一个闭包。

func是传入的函数,这里传入的是say_hello函数

inner函数又是什么?其实就是func,也就是传入的函数say_hello,再加新功能代码,假如执行inner函数,其实就是执行say_hello(),再执行新功能代码print(“byebye”)

 

上段总结一句话,经过装饰器后,new_sayhello就是一个指向inner函数的函数,执行new_sayhello就相当执行inner函数,而执行inner函数,就等于执行say_hello,再加执行新添加的代码(新加代码可以添加到func()前面和后面)

 

感觉说得有点啰嗦,个人小结为主,欢迎交流。

继续:装饰器在python中使用有一个固定语法,如装饰器(就上面那个吧)

 

def w1(func):          

    def inner():          

        func()                

        print(“byebye”)        # 新增加的功能代码

    return inner        

 

装饰器装饰函数的写法:

@w1

def fn():

    函数代码

 

这样写,解释器读到这里时,相当执行fn=w1(fn)

这里fn与原函数名fn相同,但执行完成后fn就不是原来的fn了,而是改造后的fn

再啰嗦几句,按上面的装饰器理解,fn指向w1内的inner函数,而inner函数由原函数fn和新功能代码组成,哈哈!

 

而且一个装饰器可以装饰多个函数,只要在函数定义前@xxx,即可,如

@w1

def fn1():

    …

 

@w1

def fn2():

   …

 

关于装饰器,还有一些用法,如一个函数可以用多个装饰器装饰,还有关于传参,即被装饰的函数如果有传参,还有关于被装饰的函数本身有返回值的情况,这篇有点太长,先不总结了。
mygod | 阅读全文 | 回复(0) | 引用通告 | 编辑
发表评论:
请稍候,载入中。。。
公告
请稍候,载入中。。。
时间记忆
请稍候,载入中。。。
最新日志
请稍候,载入中。。。
最新评论
请稍候,载入中。。。
最新回复
请稍候,载入中。。。
我的好友
我的相册
站点信息
请稍候,载入中。。。
生活因感动而精彩,理想在创造中放飞
Powered by Oblog.