装饰器
-
什么是装饰器?
装饰器顾名思义,一个可以起到装饰作用的工具装饰器是谁? 装饰器本质还是一个函数,是一个嵌套的函数(闭包) 装饰器装饰谁? 装饰器(函数)是对现有函数功能的一个补充或增加,它可以更快速、更清晰、大批量的为函数增加功能,让代码更简单更易懂,再不变更原有函数代码的情况下为现有函数功能进行增强
-
关于函数闭包的概念
什么是闭包? 必须有一个嵌套函数(一个函数在另一个函数中) 这个嵌套函数(内函数)必须引用外部函数的变量 封闭函数必须返回嵌套函数
def outer_func(x):
print(x)
def inner_func(y):
print x + y
return inner_func
第一步理解 帮助理解装饰器的一个闭包函数:
def outer_func():
message = "hi 你好"
def inner_func():
print(message)
return inner_func()
调用:outer_func()
输出:hi 你好
def outer_func():
message = "hi 你好"
def inner_func():
print(message)
return inner_func
调用:my_func = outer_func()
my_func()
输出:hi 你好
第二步理解 注意这次带参数了:
def outer_func(msg):
message = msg
def inner_func():
print(message)
return inner_func
*注意:这里return的是一个函数名字(实体),并没有(),换言之,他不会执行
调用:
hello_func = outer_func("hello")
python_func = outer_func("python")
hello_func()
python_func()
输出:
hello
python
第三步理解 注意,这次“接近”装饰器了!
不仅仅是“变量”可以作为参数传入函数,“函数”也可以作为参数传入函数
#做一个可以接收“函数”做为参数的函数
def deco_func(original_func):
def wrapper_func():
return original_func()
return wrapper_func
#做一个独立函数
def show_age():
print("I am 18")
调用:deco_show_age = deco_func(show_age)
deco_show_age
输出:I am 18
第四步理解 注意,这次是真的装饰器了!
#先创建装饰器,创建装饰器逻辑
def deco_func(original_func):
def wrapper_func():
return original_func()
return wrapper_func
def show_age():
print("I am 18")
调用:deco_show_age = deco_func(show_age)
deco_show_age()
输出:I am 18
#用装饰器去“装饰”,使用装饰器去装饰
def deco_func(original_func):
def wrapper_func():
return original_func()
return wrapper_func
@deco_func
def show_age():
print("I am 18")
调用:show_age()
输出: I am 18
特别注意! 装饰器装饰的函数,会先执行装饰器“函数”,在执行被装饰函数
第五步理解 继续推进-原始函数带参数怎么办?如何提升装饰器的宽容度
def deco_func(original_func):
def wrapper_func(*args,**kwargs)
return original_func(*args,**kwargs)
return wrapper_func
@deco_func
def show_info(name,age):
print(name,age)
调用:show_info("like",22)
输出:like 22
第六步理解 装饰器可否传入参数?提高装饰器的变通性
def deco_teacher(teacher_name):
def school_teacher(original_func):
def wrapper_func(name):
return original_func(name + "老师是" + teacher_name)
return wrapper_func
return school_teacher
@deco_teacher("郭老师")
def stu1():
print("我叫",name)
调用:stu1("degang")
输出: 我叫 degang 老师是郭老师
@deco_teacher("岳老师")
def stu2():
print("我叫",name)
调用:stu2("yunpeng")
输出: 我叫 yunpeng 老师是岳老师
- 装饰器使用案例
#案例一 程序计时器 计算一段程序的执行时长
import time
def timer(func):
def wrapper():
start = time.time()
func()
end = time.time()
return end - start
return wrapper
@timer
def consumer1():
l_data = []
for x in range(1000000):
l_data.append(x)
@timer
def consumer2():
time.sleep(2)
#案例二 登录控制 装饰器控制函数访问权限
def login_required(func):
def wrapper():
pwd = input("请输入登录密码:")
if pwd == "123":
print("登录成功")
func()
else:
print("密码错误,登录失败")
return wrapper
*执行直接进入
def admin_1():
print("您已经进入管理后台1")
*询问密码
@login_required
def admin_2():
print("您已经进入管理后台2")