详解Python装饰器
2019-07-10 本文已影响0人
蕴重Liu
基础
def get_list():
print('halo')
return 'result'
get_list()
函数名:def_get_list
函数体:def get_list():
print('halo')
return 'result'
返回值:'result',默认返回None
函数的内存地址:当函数体被读进内存后的保存位置,由标识符即函数名get_list引用,即get_list指向的是函数体在内存内的保存位置。
函数名加括号:函数的调用方法,只有见到这个括号,程序会根据函数名从内存中找到函数体,然后执行它
注意:函数名、函数加括号(函数的返回值)可以被当做参数传递,也可以被当做返回值return
内部原理
def wrapper(func):
def inner(cls, *args, **kwargs):
print('func 前')
result = func(cls, *args, **kwargs)
print('func 后')
return result
return inner
@wrapper
def get_list():
print('ok')
- 把wrap函数体加载到内存中
- 读到@wrapper时,识别到是装饰器,按规矩要立即执行,于是程序开始运行wrapper
- 程序返回wrapper函数,开始执行装饰器的语法规则
规则:被装饰的函数的名字会被当作参数传递给装饰函数;装饰函数执行内部代码后,会将它的返回值赋值给被装饰的函数。
注意:@wrapper 和 @wrapper() 有区别,涉及到装饰器的高级用法
outer函数return的是inner这个函数名,而不是inner()这样被调用后的返回值
- 程序执行wrapper函数内部的内容,可在inner函数前增加装饰器。inner函数定义块被程序观察到后不会立刻执行,而是读入内存中。
- return inner,返回值是函数名,且函数名会被赋值给get_list,即 get_list = inner。此时,get_list 被 inner覆盖(实际上是get_list更改成指向inner的函数体内存地址,get_list不再指向原来函数体的内存地址),再调用 get_list 时执行 inner 函数的代码,而不是先前的函数体。变量 func 保存了 函数 get_list 在内存中的地址,通过地址执行 函数get_list-----result = func 就是这么干的
- 调用 函数get_list()时,执行的不是老的 get_list()的代码,而是inner函数的代码。