装饰器在不改变函数的原有代码的前提下给函数添加新的功能,是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼。
一、装饰器的作用
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
二、装饰器示例
例1. 无参数的函数
import time
def time_fun(func):
def wrapped_func():
print("%s called at %s" % (func.__name__, time.ctime()))
func()
return wrapped_func
@time_fun
def foo():
print("I am foo")
foo()
输出结果:
foo called at Wed Sep 26 10:14:06 2018
I am foo
上面代码理解装饰器执行行为可理解成(重点理解)
foo = time_fun(foo)
# foo先作为参数赋值给func后,foo接收指向timefun返回的wrapped_func
foo()
# 调用foo(),即等价调用wrapped_func()
# 内部函数wrapped_func被引用,所以外部函数的func变量(自由变量)并没有释放
# func里保存的是原foo函数对象
例2. 被装饰的函数有参数
import time
def time_fun(func):
def wrapped_func(a, b):
print("%s called at %s" % (func.__name__, time.ctime()))
func(a, b)
return wrapped_func
@time_fun
def foo(a, b):
print(a+b)
foo(3, 5)
输出结果:
foo called at Wed Sep 26 10:11:54 2018
8
例3. 被装饰的函数有不定长参数
import time
def time_fun(func):
def wrapped_func(*args, **kwargs):
print("%s called at %s"%(func.__name__, time.ctime()))
func(*args, **kwargs)
return wrapped_func
@time_fun
def foo(a, b, c):
print(a+b+c)
foo(2, 4, 6)
输出结果:
foo called at Wed Sep 26 10:17:22 2018
12
例4. 装饰器中的return
import time
def time_fun(func):
def wrapped_func():
print("%s called at %s" % (func.__name__, time.ctime()))
return func()
return wrapped_func
@time_fun
def foo():
print("I am foo")
@time_fun
def getInfo():
return '---test---'
foo()
time.sleep(2)
getinfo = getInfo()
time.sleep(2) # 测试用,这个时候并未输出'---test---'
print(getinfo)
输出结果:
foo called at Wed Sep 26 10:30:37 2018
I am foo
getInfo called at Wed Sep 26 10:30:39 2018
---test---
- 总结:
一般情况下为了让装饰器更通用,可以有return
个人博客:
https://blog.csdn.net/niubiqigai/article/details/82849868
网友评论