zoukankan      html  css  js  c++  java
  • 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"])
    有参装饰器
  • 相关阅读:
    <<< Tomcat运行报错IOException while loading persisted sessions: java.io.EOFException
    <<< Tomcat 部署项目There are no resources that can be added or removed from the server
    <<< tomcat启动报错StandardServer.await: create[8005]
    【LeetCode】最接近的三数之和【排序,固定k1,二分寻找k2和k3】
    【LeetCode】三数之和【排序,固定一个数,然后双指针寻找另外两个数】
    【LeetCode】最长公共前缀【二分】
    【LeetCode】盛最多水的容器【双指针+贪心 寻找最大面积】
    【LeetCode】整数反转【不能借助辅助空间,需要处理溢出】
    【LeetCode】最长回文子串【动态规划或中心扩展】
    【LeetCode】寻找两个有序数组的中位数【性质分析+二分】
  • 原文地址:https://www.cnblogs.com/caodneg7/p/10152649.html
Copyright © 2011-2022 走看看