阅读目录
一 什么是装饰器
二 装饰器需要遵循的原则
三 实现装饰器知识储备
四 高阶函数
五 函数嵌套
六 闭包
七 无参装饰器
八 装饰器应用示例
一 什么是装饰器
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器定义:本质就是函数,功能是为其他函数添加新功能
二 装饰器需要遵循的原则
1.不修改被装饰函数的源代码(开放封闭原则)
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式
三 实现装饰器知识储备
装饰器=高阶函数+函数嵌套+闭包
四 高阶函数
高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
def foo():
print('我的函数名作为参数传给高阶函数')
def gao_jie1(func):
print('我就是高阶函数1,我接收的参数名是%s' %func)
func()
def gao_jie2(func):
print('我就是高阶函数2,我的返回值是%s' %func)
return func
gao_jie1(foo)
gao_jie2(foo)
#高阶函数应用1:把函数当做参数传给高阶函数
import time
def foo():
print('from the foo')
def timmer(func):
start_time=time.time()
func()
stop_time=time.time()
print('函数%s 运行时间是%s' %(func,stop_time-start_time))
timmer(foo)
#总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式
#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
import time
def foo():
print('from the foo')
def timmer(func):
start_time=time.time()
return func
stop_time=time.time()
print('函数%s 运行时间是%s' %(func,stop_time-start_time))
foo=timmer(foo)
foo()
#总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
高阶函数总结
1.函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
2.函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
五 函数嵌套
1 def father(name):
2 print('from father %s' %name)
3 def son():
4 print('from son')
5 def grandson():
6 print('from grandson')
7 grandson()
8 son()
9
10 father('tom')
六 闭包
1 '''
2 闭包:在一个作用域里放入定义变量,相当于打了一个包
3 '''
4 def father(name):
5 def son():
6 # name='jack'
7 print('is [%s]' %name)
8 def grandson():
9 # name='wupeiqi'
10 print('is [%s]' %name)
11 grandson()
12 son()
13
14 father('jack')
七 无参装饰器
无参装饰器=高级函数+函数嵌套
基本框架
1 #这就是一个实现一个装饰器最基本的架子
2 def timer(func):
3 def wrapper():
4 func()
5 return wrapper
加上参数
1 def timer(func):
2 def wrapper(*args,**kwargs):
3 func(*args,**kwargs)
4 return wrapper
加上功能
1 import time
2 def timer(func):
3 def wrapper(*args,**kwargs):
4 start_time=time.time()
5 func(*args,**kwargs)
6 stop_time=time.time()
7 print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
8 return wrapper
加上返回值
1 import time
2 def timer(func):
3 def wrapper(*args,**kwargs):
4 start_time=time.time()
5 res=func(*args,**kwargs)
6 stop_time=time.time()
7 print('函数[%s],运行时间是[%s]' %(func,stop_time-start_time))
8 return res
9 return wrapper
使用装饰器
1 def cal(array):
2 res=0
3 for i in array:
4 res+=i
5 return res
6
7 cal=timer(cal)
8 cal(range(10))
语法糖@
1 @timer #@timer就等同于cal=timer(cal)
2 def cal(array):
3 res=0
4 for i in array:
5 res+=i
6 return res
7
8 cal(range(10))
八 装饰器应用示例
user_list=[
{'name':'alex','passwd':'123'},
{'name':'linhaifeng','passwd':'123'},
{'name':'wupeiqi','passwd':'123'},
{'name':'yuanhao','passwd':'123'},
]
current_user={'username':None,'login':False}
def auth_deco(func):
def wrapper(*args,**kwargs):
if current_user['username'] and current_user['login']:
res=func(*args,**kwargs)
return res
username=input('用户名: ').strip()
passwd=input('密码: ').strip()
for index,user_dic in enumerate(user_list):
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_user['username']=username
current_user['login']=True
res=func(*args,**kwargs)
return res
break
else:
print('用户名或者密码错误,重新登录')
return wrapper
@auth_deco
def index():
print('欢迎来到主页面')
@auth_deco
def home():
print('这里是你家')
def shopping_car():
print('查看购物车啊亲')
def order():
print('查看订单啊亲')
print(user_list)
# index()
print(user_list)
home()
user_list=[
{'name':'tom','passwd':'123'},
{'name':'jack','passwd':'123'},
]
current_user={'username':None,'login':False}
def auth(auth_type='file'):
def auth_deco(func):
def wrapper(*args,**kwargs):
if auth_type == 'file':
if current_user['username'] and current_user['login']:
res=func(*args,**kwargs)
return res
username=input('用户名: ').strip()
passwd=input('密码: ').strip()
for index,user_dic in enumerate(user_list):
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_user['username']=username
current_user['login']=True
res=func(*args,**kwargs)
return res
break
else:
print('用户名或者密码错误,重新登录')
elif auth_type == 'ldap':
print('auth')
res=func(*args,**kwargs)
return res
return wrapper
return auth_deco
#auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
#就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
@auth(auth_type='ldap')
def index():
print('欢迎来到主页面')
@auth(auth_type='ldap')
def home():
print('home')
def shopping_car():
print('shopping')
def order():
print('check order')
# print(user_list)
index()
# print(user_list)
home()