python-装饰器

装饰器:本质就是函数,功能就是为其他函数提供附加功能
原则:
1.不修改被修饰函数的源代码
2.不修改被装饰函数的代用方式

装饰器=高阶函数+嵌套+闭包

高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数

装饰器的框架
def timmer(func):
def wrapper():
func()
return wrapper()

#多运行了一次,不合格
import time
def foo():
time.sleep(3)
print('来自foo')
# def timer(func):
# start_time=time.time()
# func()
# stop_time = time.time()
# print('函数运行时间是 %s' % (stop_time-start_time))
# return func
# foo=timer(foo)
# foo()

#没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
import time
def foo():
time.sleep(3)
print('来自foo')
def timer(func):
start_time=time.time()
return func
stop_time = time.time()
print('函数运行时间是 %s' % (stop_time-start_time))

foo=timer(foo)
foo()

最后的结果
import time
def timmer(func): #func=test
def wrapper():
start_time=time.time()
func() #就是在运行test()
stop_time = time.time()
print('运行时间是%s' %(stop_time-start_time))
return wrapper

@timmer #test=timmer(test)
def test():
time.sleep(3)
print('test函数运行完毕')
test()

# res=timmer(test) #返回的是wrapper的地址
# res() #执行的是wrapper()
# @timmer 就相当于 test=timmer(test),要修饰那个函数在那个前面加


加上返回值
import time
def timmer(func): #func=test
def wrapper():
start_time=time.time()
res=func() #就是在运行test()
stop_time = time.time()
print('运行时间是%s' %(stop_time-start_time))
return '这是test的返回值'
return wrapper

@timmer #test=timmer(test)
def test():
time.sleep(3)
print('test函数运行完毕')
return '这是test的返回值'
res=test() #就是在运行wrapper
print(res)

加上参数,
import time
def timmer(func): #func=test1
def wrapper(*args,**kwargs): #test('linhaifeng',age=18) args=('linhaifeng') kwargs={'age':18}
start_time=time.time()
res=func(*args,**kwargs) #就是在运行test() func(*('linhaifeng'),**{'age':18})
stop_time = time.time()
print('运行时间是%s' %(stop_time-start_time))
return res
return wrapper

# @timmer #test=timmer(test)
def test(name,age):
time.sleep(3)
print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
return '这是test的返回值'

@timmer
def test1(name,age,gender):
time.sleep(1)
print('test1函数运行完毕,名字是【%s】 年龄是【%s】 性别【%s】' %(name,age,gender))
return '这是test的返回值'

# res=test('linhaifeng',age=18) #就是在运行wrapper
# # print(res)
# test1('alex',18,'male')

test1('alex',18,'male')

list=[1,2,3,4,5445,43543,23423]
a,*_,b=list
print(a)
print(b)
输出第一行,跟最后一个元素,中间的*_代表所有
"D:\pycharm new project\venv\Scripts\python.exe" "D:/pycharm new project/01"
1
23423

f1,f2互换位置。
f1=1
f2=2
print(f1,f2)
f1,f2=f2,f1
print(f1,f2)

自己简单写的装饰器
def auth_func(func):
def wrapper(*args,**kwargs):
username=input("用户名:\n")
passwd1=input("密码:\n")
if username=='liubi' and passwd1=='123':
res=func(*args, **kwargs)
return res
else:
print("密码用户名错误")
return wrapper

@auth_func #就是index=auth_func(index)
def index():
print("欢迎来到京东页面")
@auth_func
def home(name):
print('%s欢迎回家'%name)
index()

按照自己的理解简述一下流程
当执行index()时候,就是执行,index=auth_func(index),因为auth_func的返回值是wrapper,所以index(),就相当于wrapper()
之后执行wrapper()里面的东西。


模拟访问页面的大概流程
current_dic={'username':None,'login':False} #定义一个现在登录状态的字典
user_list=[ #定义一个已有用户的字典
{'name':'alex','passwd':'123'},
{'name':'linhaifeng','passwd':'123'},
{'name':'wupeiqi','passwd':'123'},
{'name':'yuanhao','passwd':'123'},
]
def auth_func(func):
def wrapper(*args,**kwargs):
if current_dic['username'] and current_dic['login']: #判断当前用户的登录状态,如果已经登录,可以执行代码
res = func(*args, **kwargs)
return res
username=input("用户名:\n")
passwd1=input("密码:\n")
for user_dic in user_list: #如果没有登录过,就执行输入用户名,密码,并且用户名密码比较
if username==user_dic['name'] and passwd1==user_dic['passwd']:
current_dic['username']=username #如果正确的话,记录当前的登录状态
current_dic['login']=True
res = func(*args, **kwargs) #并且运行函数
return res
else:
print('用户名密码不正确')
return wrapper
@auth_func
def index():
print("欢迎来到京东页面")
@auth_func
def home(name):
print('%s欢迎回家'%name)
index()
home('alex')


带参数功能的装饰器验证:
user_list=[
{'name':'alex','passwd':'123'},
{'name':'linhaifeng','passwd':'123'},
{'name':'wupeiqi','passwd':'123'},
{'name':'yuanhao','passwd':'123'},
]
current_dic={'username':None,'login':False}

def auth(auth_type='filedb'):
def auth_func(func):
def wrapper(*args,**kwargs):
print('认证类型是',auth_type)
if auth_type == 'filedb':
if current_dic['username'] and current_dic['login']:
res = func(*args, **kwargs)
return res
username=input('用户名:').strip()
passwd=input('密码:').strip()
for user_dic in user_list:
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_dic['username']=username
current_dic['login']=True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
elif auth_type == 'ldap':
print('鬼才特么会玩')
res = func(*args, **kwargs)
return res
else:
print('鬼才知道你用的什么认证方式')
res = func(*args, **kwargs)
return res

return wrapper
return auth_func

@auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type --->index=auth_func(index)
def index():
print('欢迎来到京东主页')

@auth(auth_type='ldap') #再这里加上去要传的值
def home(name):
print('欢迎回家%s' %name)



@auth(auth_type='sssssss')
def shopping_car(name):
print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))



# print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# home('产品经理')
shopping_car('产品经理')

 

posted @ 2018-05-09 09:58  夏天的麦田  阅读(82)  评论(0)    收藏  举报