python中装饰器的原理

装饰器这玩意挺有用,当时感受各类绕,如今终于绕明白了,俺滴个大爷,仍是要慢慢思考才能买明白各类的真谛,没事就来绕一绕函数

 

def outer(func):
def inner():
print("认证成功")
result=func()
print("登陆成功")
return result
return inner
@outer
def OA():
print("OA接口")

这里面须要注意的是:
  • @outer和@outer()有区别,没有括号时,outer函数依然会被执行,这和传统的用括号才能调用函数不一样,须要特别注意!
  • 是OA这个函数名(而不是OA()这样被调用后)当作参数传递给装饰函数outer,也就是:func = OA,@outer等于outer(OA),实际上传递了OA的函数体,而不是执行OA后的返回值。
  • outer函数return的是inner这个函数名,而不是inner()这样被调用后的返回值。
 1. 程序开始执行outer函数内部的内容,一开始它又碰到了一个函数,inner函数定义块被程序观察到后不会马上执行,而是读入内存中。
 2. 再往下,碰到return inner,返回值是个函数名,而且这个函数名会被赋值给OA这个被装饰的函数,也就是OA = inner,此时OA函数被新的函数inner覆盖了(其实是OA这个函数名更改为指向inner这个函数名指向的函数体内存地址,OA再也不指向它原来的函数体的内存地址),再日后调用OA的时候将执行inner函数内的代码,而不是先前的函数体。那么先前的函数体去哪了?还记得咱们将OA当作参数传递给func这个形参么?func这个变量保存了老的函数在内存中的地址,经过它就能够执行 老的函数体,你能在inner函数里看到result = func()这句代码,它就是这么作的!
 3.接下来,尚未结束,依然经过OA()的方式调用OA 函数时,执行的就再也不是老的OA函数的代码,而是inner函数的代码。在本例中,它首先会打印个“认证成功”的提示,而后,它会执行func函数并将返回值赋值个变量result,这个func函数就是老的OA函数;接着,它又打印了“登录成功”的提示;最后返回result这个变量。咱们能够用 r = OA()的方式接受result的值。
 4.仅仅是添加了一个装饰函数,就实现了咱们的需求,在函数调用前先认证,调用后写入日志,这就是装饰器的最大做用。