别惹大魔王2,史大平,料理机和榨汁机的区别
简单说就是在被装饰的函数前后增加新功能,
而不用修改函数内部结构和调用方式的特殊语法
def out(fun): def inner(): print('函数前新增功能...') fun() print('函数后新增功能...') return inner @out def test(): print('---test---') test()
输出
函数前新增功能... ---test--- 函数后新增功能...
此时的@out
就是装饰器,
同时也可以看到装饰器只能在被修饰函数整体的前后[增加]功能,
而不能[修改]被装饰的函数的功能
补充:
1.函数执行的顺序是由上自下,由右至左
2.函数名仅仅是一个变量而已
3.@out
等价于test = out(test)
当执行到@out
时,三个小步骤
out
函数传递被装饰函数的引用,并用形参fun
指向此时变量test
指向的函数引用out()
,获得内层变量inner
指向的函数的引用test
指向inner
函数的引用def out(fun): def inner(*args, **kwargs): print('函数前新增功能...') fun(*args, **kwargs) print('函数后新增功能...') return inner
def first(first_func): # first_func 记录了第二次 test 指向,即 final_inner 的引用 ,print('---final-2---')和final_func() print('---first-1---') def first_inner(): print('---first-2---') first_func() return first_inner def final(final_func): # final_func 记录了第一次 test 指向,即print('---test---') print('---final-1---') def final_inner(): print('---final-2---') final_func() return final_inner @first # test = first(test) 第二次改变的test指向first_inner,从右向左执行 @final # test = final(test) 第一次改变的test指向final_inner,从右向左执行 def test(): print('---test---') test()
结果
---final-1--- ---first-1--- ---first-2--- ---final-2--- ---test---
@first
装饰器,但是@first
下面没有函数,则等待下面语句获得函数时再接着执行@final
装饰器,打印[---final-1---
],将被装饰的函数test
的引用传递给形参final_func
记录,final_inner
函数的引用(第一次改变test
的指向)给变量test
@first
下面有了函数test
,接着去执行@first
装饰器,打印[---first-1---
],将此时test
记录的final_inner
的引用传递给形参first_func
记录,first_inner
的引用给了变量test
(第二次改变test
指向)test()
,此时test
记录的是first_inner
的引用,相当于执行first_inner()
,打印[---first-2---
]first_func()
,first_func
存的是final_inner
的引用,相当于执行力final_inner()
,打印[---final-2---
]final_func()
,final_func
存的是test
最开始的引用,打印[---test---
]先执行了后一个的装饰器的的外层函数final
然后执行前一个装饰器的外层函数first
然后执行前一个装饰器first_inner
接着执行后一个函数的内部函数final_inner
最后执行test
本身
如果一个类重写了__call__()
方法,那么这个类可以被用作装饰器,称为类装饰器
类装饰器的基本形式
class A(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print('函数前新增功能...') self.func() print('函数后新增功能...') @A # test = A(test) 以A类为模板,创建实例对象test def test(): print('---test---') test()
def out_out(x): def out(fun): def inner(*args, **kwargs): print('函数前新增功能...%s' % x) fun(*args, **kwargs) print('函数后新增功能...%s' % x) return inner return out @out_out('测试') # 相当于 test = out_out(111)(test) def test(): print('---test---')
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
新手学习Python2和Python3中print不同的用法
Python基于os.environ从windows获取环境变量
网友评论