python—装饰器

一:什么叫装饰器

      1.装饰器:本质就是函数,为其他函数添加附加功能

                     (原则:不修改被修饰函数的源代码,不修改被修饰函数的调用方法)

 1 import time
 2 def cal(l):
 3     start_time=time.time()
 4     res=0
 5     for i in l:
 6         res+=i
 7     stop_time=time.time()
 8     print('函数的运行时间是%s' %(stop_time-start_time))
 9     return res
10 print(cal(range(100)))
11 #结果:函数的运行时间是0.0
12 #     4950

     

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

         【1】高阶函数定义:

1 1.函数接收的参数是一个函数名
2 2.函数的返回值是一个函数名
3 3.满足上述条件任意一个,都可称之为高阶函数
 1 #函数接收的参数是函数名
 2 import time
 3 def foo():
 4     print('nihao')
 5 def test(func):
 6     # print(func)
 7     start_time=time.time()
 8     func()
 9     stop_time=time.time()
10     print('函数的运行时间是 %s' %(stop_time-start_time))
11 test(foo)  #接收的参数是一个函数名foo
12 #结果:nihao
13 #     函数的运行时间是 0.0
 1 #函数的返回值是函数名
 2 def foo():
 3     print('from the foo')
 4 def test(func):
 5     return func
 6 res=test(foo)
 7 print(res)  #res的内存地址
 8 res()  #res加括号直接运行出来
 9 #结果:<function foo at 0x0000013458554950>
10 #     from the foo

         【2】函数闭包(嵌套):

1 #函数闭包,一层套一层,关闭的一层套一层,把变量闭包到里面
2 def father(name):
3     def son():
4         name='zy'
5         print('爸爸是%s' %name)
6     son()
7 father('zy')   #永远往上层找
8 #结果:爸爸是zy

#函数闭包补充:解压序列

 1 >>>list=[1,2,3,8,9,6]
 2 >>>a.*_.c=list
 3 >>>a
 4 1
 5 >>>c
 6 6
 7 #取列表的第一个与最后一个元素
 8 >>>f1=1
 9 >>>f2=2
10 >>>f1,f2=f2,f1
11 #直接交换f1,f2的值

      3.装饰器基本实现

 1 #装饰器的框架
 2 def timmer(func):
 3     def wrapper():
 4         print(func)
 5         func()
 6     return wrapper
 7 例子:
 8 import time
 9 #装饰器的框架
10 def timmer(func):
11     def wrapper():
12         #print(func)
13         start_time=time.time()
14         func()  #就是在运行test()
15         stop_time=time.time()
16         print('运行时间是%s' %(stop_time-start_time))
17     return wrapper
18
19 def test():
20     time.sleep(3)
21     print('test函数运行完毕')
22 
23 res=timmer(test)  #返回的是wrapper的地址
24 res() #执行的是wrapper()
25 #结果:test函数运行完毕
26 #    运行时间是3.01176118850708
27 
28 res=timmer(test)  #返回的是wrapper的地址
29 res() #执行的是wrapper()
30 #上面这块可以修改成:
31 test=timmer(test)
32 test()
33 还可以使用语法糖#@timmer(python提供的)替代赋值,在def test():上面加@timmer装饰器名字就可以

     #函数闭包加参数:

 1 import time
 2 #装饰器的框架
 3 def timmer(func):
 4     def wrapper(name,age):
 5         #print(func)
 6         start_time=time.time()
 7         res=func(name,age)  #就是在运行test()
 8         stop_time=time.time()
 9         print('运行时间是%s' %(stop_time-start_time))
10         return res
11     return wrapper
12 
13 @timmer  #test=timmer(test)
14 def test(name,age):
15     time.sleep(3)
16     print('test函数运行完毕,名字是【%s】 年龄是【%s】' %(name,age))
17     return '这是test的返回值'
18 
19 # res=timmer(test)  #返回的是wrapper的地址
20 res=test('zy',18) #执行的是wrapper()
21 print(res)
22 #结果:test函数运行完毕,名字是【zy】 年龄是【18】
23 #     运行时间是3.0002963542938232
24 #     这是test的返回值

    #函数闭包为函数加上认证功能

 1 def auth_func(func):
 2     def wrapper(*args,**kwargs):
 3         username=input('用户名:').strip()
 4         passwd= input('密码:').strip()
 5         if username=='周圆' and passwd=='123':
 6             res=func(*args,**kwargs)
 7             return res
 8         else:
 9             print('用户名或密码错误!')
10     return wrapper
11 @auth_func
12 def index():
13     print('欢迎来到京东主页')
14 @auth_func
15 def home(name):
16     print('欢迎回家%s' %name)
17 @auth_func
18 def shopping_car(name):
19     print('%s的购物车里有[%s]' %(name,'奶茶'))
20 
21 index()
22 home('周圆')
23 shopping_car('周圆')
24 #结果:用户名:周圆
25 #     密码:123
26 #     欢迎来到京东主页
27 #     用户名:周圆
28 #     密码:1234
29 #     用户名或密码错误!
30 #     用户名:周圆
31 #     密码:123
32 #     周圆的购物车里有[奶茶]

     #函数闭包模拟session:

user_dic={'username':None,'login':False}

def auth_func(func):
    def wrapper(*args,**kwargs):
        if user_dic['username'] and user_dic['login']:
            res = func(*args, **kwargs)
            return res
        username=input('用户名:').strip()
        passwd= input('密码:').strip()
        if username=='周圆' and passwd=='123':
            user_dic['username']=username
            user_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)
@auth_func
def shopping_car(name):
    print('%s的购物车里有[%s]' %(name,'奶茶'))

index()
home('周圆')
shopping_car('周圆')

#用户名:周圆
#密码:123
#欢迎来到京东主页
#欢迎回家周圆
#周圆的购物车里有[奶茶]
原文地址:https://www.cnblogs.com/zhouyuan666/p/9539077.html