Python装饰器

定义

  本质就是函数,功能 为其它函数添加附加功能

  原则:

  • 不修改被修饰函数的源代码
  • 不修改被修饰函数的调用方式

  装饰器的知识储备

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

  这里面要明确高阶函数的定义

 1 import time#导入时间模块儿
 2 def foo(func):  # func = test
 3     def bar(*args,**kwargs):
 4         start_time = time.time()
 5         res=func(*args,**kwargs)  # 这里就是在运行test()  赋予变量
 6         stop_time = time.time()
 7         print("狼来了的时间为%s" %(stop_time-start_time))
 8         return res # 返回test()的值
 9     return bar
10 @foo  # @foo 相当于 test=foo(test) 调用foo函数并将test传给func
11 def test(name,age):
12     time.sleep(1)
13     print("名字叫%s年龄为%s的狼来了" %(name,age))
14     return "村里的羊被吃了"
15 ret = test("灰太狼",age=10)  # test()意在运行bar()   # 输出res的返回值
16 print(ret)
装饰器模型

分布式讲解:

高阶函数的定义

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

    以上条件任意满足一条,都可以称之为高阶函数

 1 def foo():
 2     print('我的函数名字作为参数传给高阶函数啦')
 3 def gao_jie1(func):   # 传函数名  func = foo
 4     print('我就是高阶函数1号,我接收的参数名是%s' %func)
 5     func() # 意在运行 foo()函数
 6 
 7 def gao_jie2(func): # func = foo
 8     print('我就是高阶函数2号,我的返回值是%s' %func)
 9     return func  # 此时func为返回foo的的内存地址
10 
11 gao_jie1(foo)
12 print(gao_jie2(foo))
13 
14 输出
15 我就是高阶函数1号,我接收的参数名是<function foo at 0x000001FDF179F598>
16 我的函数名字作为参数传给高阶函数啦
17 我就是高阶函数2号,我的返回值是<function foo at 0x000001FDF179F598>
18 <function foo at 0x000001FDF179F598>
高阶函数示范
 1 import time
 2 def foo():
 3     time.sleep(2)
 4     print("狼来了")
 5 def test(func):  # func = foo
 6     start_time = time.time()
 7     func()  # func()意在调用 foo()函数
 8     stop_time = time.time()
 9     print("狼来的时间为%s" %(stop_time-start_time))
10 test(foo) # 调用test()函数 并用函数名为参数传进去
将函数名为参数传给高阶函数

    总结:1、函数接收的参数是一个函数名

        作用:在不修改函数源代码的前提下添加新功能

        不足:改变了函数的调用方式

#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
import time
def foo():
    time.sleep(2)
    print("狼来了")
def test(func): # func = foo的内存地址
    start_time = time.time()
    return func # 返回值为foo的内存地址
    stop_time = time.time()
    print("狼来的时间为%s" %(stop_time-start_time))
foo = test(foo) # 调用test函数并将函数名foo做为参数传进去
print(foo) # 输出返回值的结果 foo的内存地址
foo()  # 运行foo()函数

#没有改变函数foo的调用方式,但是也没有给函数增加新功能
函数返回值是函数名

   总结: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 father('舒克')
10 
11 输出
12 from father 舒克
13 from son
14 from grandson
函数嵌套

闭包

 1 '''
 2 闭包:在一个作用域里放入定义变量,相当于打了一个包
 3 '''
 4 def father(name):
 5     def son():
 6         # name='alex'
 7         print('我爸爸是 [%s]' %name)
 8         def grandson():
 9         # name='wupeiqi'
10             print('我爷爷是 [%s]' %name)
11         grandson()
12     son()
13 father('舒克')
闭包示例

无参装饰器=高阶函数+嵌套函数

    基本框架

1
2
3
4
5
# 无参装饰器,这是一个实现装饰器最基本的框架
def timmer(func):
    def bar():
        func()
    return bar

    加入参数之后

1
2
3
4
5
# 带参数装饰器
def timmer(func):
    def bar(*args,**kwargs):
        func(*args,**kwargs)
    return bar

    加入时间功能

1
2
3
4
5
6
7
8
9
# 加一个时间的小功能
import time
def timmer(func):
     def bar(*args,**kwargs):
         start_time=time.time()
         func(*args,**kwargs)
        stop_time=time.time()
         print("狼来的时间为%s" %(stop_time-start_time))
     return bar

    加入函数运行的返回值

1
2
3
4
5
6
7
8
9
10
# 加入函数返回值
import time
def timmer(func):
     def bar(*args,**kwargs):
         start_time=time.time()
         res=func(*args,**kwargs)
         stop_time=time.time()
         print("狼来的时间为%s" %(stop_time-start_time))
        return res
     return bar

    使用装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time
def timmer(func):
    def bar(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print("博尔特跑10米的时间为%s" %(stop_time-start_time))
        return res
    return bar
# 使用装饰器
def test():
    time.sleep(1)
    print("到达终点")
    return "世界飞人"
test=timmer(test)
print(test())
 
输出
到达终点
博尔特跑10米的时间为1.0006155967712402
世界飞人

    语法糖@

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time
def timmer(func):
    def bar(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print("博尔特跑10米的时间为%s" %(stop_time-start_time))
        return res
    return bar
# 使用装饰器
@timmer  # @timmer就相当于 test=timmer(test)
def test():
    time.sleep(1)
    print("到达终点")
    return "世界飞人"
# test=timmer(test)
print(test())  # test()是在运行bar()函数

应用示例

user_list=[
    {'name':'alex','passwd':'123'},
    {'name':'linhaifeng','passwd':'123'},
    {'name':'wupeiqi','passwd':'123'},
    {'name':'yuanhao','passwd':'123'},
    {'name':'病毒尖er','passwd':'123'},
]
current_user={'username':None,'login':False}

def auth_func(func):     # 用户登陆验证
    def bar(*args,**kwargs):
        if current_user["username"] and current_user["login"]:
            res = func(*args,**kwargs)
            return res
        for i in range(3):
            username = input("请输入用户名:").strip()
            passwd = input("请输入密码:").strip()
            for item in user_list:
                if username == item["name"] and passwd == item["passwd"]:
                    current_user["username"] = username
                    current_user["login"] = True
                    res=func(*args,**kwargs)
                    return res
        else:
            print("您输入的用户名或者密码有误")
    return bar
@auth_func # 相当于index=auth_func(index)
def index():
    print("欢迎来到京东商城" )
@auth_func # 相当于home=auth_func(home)
def home(name):
    print("%s欢迎回家" %name)
@auth_func # 相当于shop_car=auth_func()
def shop_car(name):
    print("%s的购物车是空的,赶紧购物咯" %name)

index()
home(current_user["username"])
shop_car(current_user["username"])
无参装饰器

 

 1 user_list=[
 2     {'name':'alex','passwd':'123'},
 3     {'name':'linhaifeng','passwd':'123'},
 4     {'name':'wupeiqi','passwd':'123'},
 5     {'name':'yuanhao','passwd':'123'},
 6     {'name':'病毒尖er','passwd':'123'},
 7 ]
 8 current_user={'username':None,'login':False}
 9 def auth(auth_type="file"):
10     def auth_func(func):     # 用户登陆验证
11         def bar(*args,**kwargs):
12             if auth_type == "file":
13                 if current_user["username"] and current_user["login"]:
14                     res = func(*args,**kwargs)
15                     return res
16                 for i in range(3): # 给用户三次重复输入的机会 防止进入其它功能进入下一层
17                     username = input("请输入用户名:").strip()
18                     passwd = input("请输入密码:").strip()
19                     for item in user_list:
20                         if username == item["name"] and passwd == item["passwd"]:
21                             current_user["username"] = username
22                             current_user["login"] = True
23                             res=func(*args,**kwargs)
24                             return res
25                 else:
26                     print("您输入的用户名或者密码有误")
27             elif auth_type == "ldap":
28                 print("快点告诉你,你用我画的蜡笔")
29                 res = func(*args,**kwargs)
30                 return res
31         return bar
32     return auth_func
33 @auth(auth_type="file")
34 def index():
35     print("欢迎来到京东商城" )
36 @auth(auth_type="ldap")  # 传参数 类型对应
37 def home(name):
38     print("%s欢迎回家" %name)
39 @auth(auth_type="file")
40 def shop_car(name):
41     print("%s的购物车是空的,赶紧购物咯" %name)
42 
43 index()
44 home(current_user["username"])
45 shop_car(current_user["username"])
有参装饰器

 

posted @ 2019-03-17 16:23  初遇ぃ  阅读(146)  评论(0编辑  收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中 //一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中