python—装饰器
1、装饰器
本质上函数,为其他函数添加附加功能
— 不修改被修饰函数的源代码
— 不修改被修饰函数的源代码调用方式
装饰器 = 高阶函数+函数嵌套+闭包
import time
### 定义装饰器
def timmer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
stop_time = time.time()
print('函数运行时间为:',(stop_time-start_time))
return res
return wrapper
@timmer
def cal(l):
res = 0
for i in l:
res += i
time.sleep(0.1)
return res
print(cal(range(5)))
2、高阶函数
函数的参数或返回值是函数名(函数名是内存地址)
### 高阶函数(函数参数是函数名),修改函数调用方式
import time
def foo():
print('来来来啊俩')
def test(func):
print(func)
start_time = time.time()
func()
stop_time = time.time()
print('函数运行时间为:',(stop_time-start_time))
test(foo) ## 原来的调用方式 foo()
### 高阶函数(函数返回值是函数名)
def foo():
print('from the foo')
def test(func):
return func
foo = test(foo)
foo()
import time
def foo():
print('from the foo')
## 不修改foo源代码和调用方式
def timmer (func):
start_time = time.time()
func()
stop_time = time.time()
print('函数运行时间为:',(stop_time-start_time))
return func
foo = timmer(foo)
foo()
### 多运行了一次 foo()
3、函数嵌套
函数内定义另一个函数
def first(name):
print('第一层 %s' %name)
def second():
print('第二层')
print(locals())
## 两个局部变量 name和second() {'name': 'gogo', 'second': <function first.<locals>.second at 0x006A1150>}
first('gogo')
def first(name):
name = 'haha'
print('第一层 %s' %name)
def second():
name = 'kako'
print('第二层%s' %name)
second()
first('gogo')
## 第一层 haha
## 第二层kako
4、装饰器框架
## 装饰器框架 : 高阶函数+函数嵌套
import time
def timmer(func):
def wrapper():
start_time = time.time()
func() ### 执行rest()
end_time = time.time()
print('函数运行时间为:',(end_time-start_time))
return wrapper
@timmer ## 相当于 test = timmer(test)
def test():
time.sleep(0.1)
print('test函数运行完毕')
# test = timmer(test) ## 返回wrapper的地址
# test() ## 执行wrappper()
test()
## test函数运行完毕
##函数运行时间为: 0.10100579261779785
补充:
## 交换数值 a=1 b=2 a,b=b,a print(a,b)
5、装饰器例子
# 为函数加上认证功能
# 全局变量模拟session
# 装饰器加参数
user_list = [
{'username':'Amy','passwd':'123'},
{'username':'Lisa', 'passwd': '123'},
{'username':'Lucy', 'passwd': '123'},
{'username':'Bob', 'passwd': '123'},
{'username':'Fly', 'passwd': '123'},
]
# 记录当前用户状态
current_dic = {'username':None,'login':False}
def auth(auth_type='filedb'): ## 装饰器加参数
def auth_func(func):
def wrapper(*args,**kwargs):
if current_dic['username'] and current_dic['login']:
res = func(*args, **kwargs)
return res
username = input('用户名:').strip()
passwd = input('密码:').strip()
for user_li in user_list:
if username == user_li['username'] and passwd == user_li['passwd']:
current_dic['username'] = username
current_dic['login'] = True
res = func(*args, **kwargs)
return res
else:
print('用户名或密码错误!')
return wrapper
@auth(auth_type='filedb') ## auth_func=auth(auth_type='filedb') ---> @auth_func附加了auth_tupe参数 ---> index = auth_func(index)
def index():
print('xx欢迎您!!')
@auth(auth_type='filedb')
def home(name):
print('欢迎回到%s的主页!!' %name)
index()
home('abc')

浙公网安备 33010602011771号