Python基础-----装饰器

一、装饰器定义

器即函数;装饰即修饰,意指为其他函数添加新功能;

装饰器定义:本质就是函数,功能是为其他函数添加新功能

二、装饰器的原则

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

三、高阶函数

满足如下条件之一就可称之为高阶函数

1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名

高阶函数总结

1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式
2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能

四、闭包
闭包:在一个作用域里放入定义变量(或嵌套函数),相当于打了一个包
想要给内部传入参数,用闭包的话只需要在最外部传入即可
1 def father(name):
2    def son():
3         def grandson():
4             print('from %s'%name)
5         grandson()
6    son()
7 
8 father('Meanwey')

五、装饰器框架实现
 1 import time
 2 def timmer(func):    #func = test
 3    def wrapper():
 4       start_time = time.time()
 5       func()       #执行test函数
 6       stop_time = time.time()
 7       print('运行时间%s'%(stop_time - start_time))
 8    return wrapper
 9 
10 def test():
11    time.sleep(3)
12    print('函数运行完毕')
13 
14 test = timmer(test)   #返回的是wrapper的函数地址
15 test()           #执行wrapper函数,内部再运行test函数
  上面代码符合装饰器的基本原则,但是调用test函数之前进行了赋值操作

六、装饰器语法糖
@装饰函数 (将该句代码放置于修饰函数前即可)
就上例来讲,@timmer 就相当于 test = timmer(test)
 1 import time
 2 def timmer(func):    #func = test
 3    def wrapper():
 4       start_time = time.time()
 5       func()       #执行test函数
 6       stop_time = time.time()
 7       print('运行时间%s'%(stop_time - start_time))
 8    return wrapper
 9 
10 @timmer   #等同于test = timmer(test)
11 def test():
12    time.sleep(3)
13    print('函数运行完毕')
14 
15 test()

七、加上返回值
 1 import time
 2 def timmer(func):    #func = test
 3    def wrapper():
 4       start_time = time.time()
 5       res = func()       #执行test函数
 6       stop_time = time.time()
 7       print('运行时间%s'%(stop_time - start_time))
 8       return res
 9    return wrapper
10 
11 @timmer   #等同于test = timmer(test)
12 def test():
13    time.sleep(3)
14    print('函数运行完毕')
15    return '这是test的返回值'
16 a = test()   #实际执行wrapper函数
17 print(a)

八、加上参数
 1 import time
 2 def timmer(func):    #func = test
 3    def wrapper(name,age):
 4       start_time = time.time()
 5       res = func(name,age)       #执行test函数,参数来自wrapper接收的参数
 6       stop_time = time.time()
 7       print('运行时间%s'%(stop_time - start_time))
 8       return res
 9    return wrapper
10 
11 @timmer   #等同于test = timmer(test)
12 def test(name,age):
13    time.sleep(3)
14    print('我叫%s,年龄%d'%(name,age))
15    return '这是test的返回值'
16 a = test('alex',18)   #实际执行wrapper函数

  但是参数是固定的,不适用于所有函数,则改变如下:
 1 import time
 2 def timmer(func):    #func = test
 3    def wrapper(*args,**kwargs):        #可以用*  **来传入多参数
 4       start_time = time.time()
 5       res = func(*args,**kwargs)       #执行test函数,参数来自wrapper接收的参数
 6       stop_time = time.time()
 7       print('运行时间%s'%(stop_time - start_time))
 8       return res
 9    return wrapper
10 
11 @timmer   #等同于test = timmer(test)
12 def test(name,age):
13    time.sleep(3)
14    print('我叫%s,年龄%d'%(name,age))
15    return '这是test的返回值'
16 
17 @timmer
18 def test1(name,age,gender):
19    time.sleep(3)
20    print('我叫%s,年龄%d,性别%s'%(name,age,gender))
21    return '这是test的返回值'
22 a = test('alex',18)   #实际执行wrapper函数
23 b = test1('tony',22,'male')   #该处将'tony',22,'male'参数放入*args == *('tony',22,'male')(一一对应,相当于解压)

九、列表解压
  如要获取列表的第一个和最后一个值,不用索引来取
1 l = [10,2,3,4,5,7,5,4,2,32]
2 first_num,*other_num,last_num = l   #  *+变量名   表示中间的所有元素
3 print(first_num,last_num)
4 print(*other_num)

  如需互换两个变量的值
1 a = 1
2 b = 2
3 a,b = b,a
4 print(a,b)

十、实例(验证功能装饰器)
 1 user_list = [
 2          {'name':'a','password':'123'},
 3          {'name':'b','password':'123'},
 4          {'name':'c','password':'123'},
 5          {'name':'d','password':'123'}
 6 ]   #所有用户信息列表(值为字符串类型)
 7 
 8 current_user = {'username':None,'login':False}    #记录用户当前登录状态
 9 
10 def auth_func(func):
11    def wrapper(*args,**kwargs):
12       if current_user['username'] and current_user['login']:   #如果已经登录,则无需登陆
13          res = func(*args,**kwargs)
14          return res
15       username = input('用户名:').strip()   #上面if不成立,则登录
16       password = input('密码:').strip()
17       for user_dic in user_list:    #for遍历的是用户列表的中用户信息字典
18          if username == user_dic['name'] and password == user_dic['password']: #登录验证
19             current_user['username'] = username   #登录成功,更改用户状态
20             current_user['login'] = True
21             res = func(*args,**kwargs)
22             return res
23       else:   #该处else没放在if下是因为,要遍历所有的用户列表才能判断是否真的有错
24          print('用户名或密码错误,请重新登录!')
25    return wrapper
26 
27 @auth_func
28 def home(name):
29    print('欢迎 %s 来到主页'%name)
30 
31 @auth_func
32 def shopping_car(name):
33    print('%s 的购物车里有:学习用品,生活用品!'%name)
34 
35 home('Jerry')
36 print(current_user)
37 shopping_car('Jerry')

 

posted @ 2018-10-03 23:29  Meanwey  阅读(231)  评论(0编辑  收藏  举报