python基础之:九步认识装饰器
step1.
先看个代码吧:
def f(): print('111111') f=lambda a:a +100 #覆盖上面的函数f print(f) #函数名指函数所在内存中的位置,入带后面括号表示执行函数 print(f(10)) out: <function <lambda> at 0x101b7b6a8> 110
以上code说明:
1.在def 函数时,以顺序执行,如果相同的函数名,会被最后函数覆盖以前的
2.如果直接func名而没有后面的圆括号的话,只指向函数在内存中的位置
3.lambda表达式会自动return结果,而def需要定义return值
step2:
python中可想函数传递参数,并将参数转变为本地变量存在于函数内部。
def f(x): print(locals()) f('a') out: {'x': 'a'}
step3:
python函数中可以嵌套函数,这就说明了我们可以在函数里定义函数,而且现有的作用域和函数的变量生存周期依旧适用。
def outer(): x='hello world' def inner(): print(x) #1 inner() #2 outer() out: hello world
#1 中发生了什么,函数inner需要一个x的变量,去查找x的变量,但本地变量中没有,查找失败后去上一层的作用域中去寻找,而x变量在上一层函数的作用域中。
对outer来说,x是本地变量,但函数inner可以访问封闭的作用域
#2 中,调用了inner函数,python解释器会优先查找本地的变量x
step4:
def outer(): x='hello world' def inner(): print(x) return inner #1 foo=outer() #2 print(foo) foo() out: <function outer.<locals>.inner at 0x10137b6a8> hello world
#1与step3区别,我们将函数inner的内存地址给返回了
#2,将函数outer的返回值赋值于变量foo,也就是说,foo() 执行时,实际上执行了inner()。
但inner函数集成了outer函数中的本地变量,outer外面,没有x这个变量,为什么能执行呢??
这是因为python中有一个叫”函数闭包”的特性,怎么理解呢?嵌套定义在非全局作用域中的函数,能够记住它在被定义时候它所处的封闭命名空间。
函数outer每次在被调用的时候,函数inner都会被重新定义,现在变量x的值不会变化,所以每次执行的逻辑和结果都一样,那么如果x是变化的呢?
step5:
def outer(x): def inner(): print(x) #1 return inner print1=outer(1) print2=outer(2) print1() print2() out: 1 2
从这个我们能够看到“闭包”:被函数记住的封闭作用域,能够被用来创建自定义的函数。
事实上,我们并不是传递参数1或2给inner函数,我们实际上是定义了能够打印各种数字的自定义版本。
step6:装饰器
终于说到装饰器上了。。。。。
装饰器其实就是一个闭包而已,把func作为参数,然后返回一个替代版的函数,其实真正执行的是inner内部的流程
def outer(func): def inner(): print('before some_func') res = func() print(res+1) print(('after some_func')) return res+1 return inner def foo(): return 1 f1=outer(foo) #1 f1() out: before some_func 2 after some_func
在这我们可以认为变量f1是函数foo的的装饰器。但这么写有点太low了是不是,所以python中有个优雅的@符号,太装逼了。。。可以这么写:
def outer(func): def inner(): print('before some_func') res = func() print(res+1) print(('after some_func')) return res+1 return inner @outer def foo(): return 1 foo() out: before some_func 2 after some_func
看到没,执行结果一毛一样有木有。
step8:
def outer(func): def inner(*args,**kwargs): print('before some_func') res = func(*args,**kwargs) print(('after some_func')) return res return inner @outer def foo(): print(111) foo() @outer def foo1(li,d): print('args:%s'%li) print('kwargs:%s'%d) foo1('fuck','U') =============== out: before some_func 111 after some_func before some_func args:fuck kwargs:U after some_func
step9:
多层装饰器
装饰器类似于俄罗斯套娃,可以一层套一层,譬如:
def outer(func): def inner(*args,**kwargs): print('before some_func') res = func(*args,**kwargs) print(('after some_func')) return res return inner @outer1 @outer def foo1(li,d): print('args:%s'%li) print('kwargs:%s'%d) foo1('fuck','U') ==================== out: before:this is outer1 before some_func args:fuck kwargs:U after some_func after:this is outer1 again!
未完待续。。。