• Python之函数装饰器


            在实际中,我们可能需要在不改变函数源代码和调用方式的情况下,为函数添加一些新的附加功能,能够实现这种功能的函数我们将其称之为装饰器。装饰器本质上其实还是是一个函数,用来装饰其它函数,为函数添加一些附加功能。下面我将具体讲解一下如何实现装饰器。

            具体剖析上面的叙述,我们可以分析出装饰器应该具有的性质:

        1.不能修改被装饰的函数的源代码(在不修改被装饰函数的源代码的情况下,为其添加功能)

        2.函数的调用方式不能被修改(函数的调用方式不用被修改) 

           以上两个性质实则对应着函数里面的三个知识点:函数即‘变量’、高阶函数、函数嵌套。可以说 高阶函数+函数嵌套 = >装饰器

    函数即变量

      我们知道变量有内存回收机制,函数和变量一样也有同样的性质,函数在内存中的存储方式就可以看做是一段存储在内存中的代码,和变量没有任何区别。
    1 def foo():
    2     print('you are the best girl!\n')
    print(foo)
      如上面这段代码,执行print的时候,会同变量一样,返回一个函数存储在内存的首地址;当为foo加上括号才表示执行该函数。
    高阶函数

    满足下列两个条件之一就叫做高阶函数:把一个函数名当做实参传给另外一个函数(注意是函数名,如果函数名后面加了括号表示传递的是该函数的返回值,
    不能算作高阶函数,后同);
    返回值中包含函数名
    import time
    def add():
        print('a+b = 10')
        time.sleep(2)
    
    def decorate(func):
        start_time = time.time()
        func()
        stop_time = time.time()
        print('the func run time is %s'%(stop_time - start_time))
    
    decorate(add) #此方式可直接运行函数
    
    #函数返回,可以直接返回函数的地址,变量接收到函数地址后,可以以该变量作为函数名调用函数
    # def test2(func):
    #     func()
    #     print(func)
    #     return func
    #
    # add = test2(add)
    # add()  #add接收到函数首地址后,再加上小括号就可以直接运行该函数

    函数嵌套

    1 嵌套函数(*注意函数嵌套与函数调用的区别)
    2 def test3():
    3     print('in the test3')
    4     def next():   #相当于在test3函数里面定义了一个局部变量函数
    5         print('int the next func')
    6     next()
    7 
    8 test3()
    装饰器
    在理解了以上概念之后便可以直接上装饰器的源代码了
    #装饰器功能,检验用户是否有资格登录使用该函数,并显示登录时间
    import time
    username,password = "putin","zy123456"
    def loging(intype = 'local'):#这一层是接收在使用装饰器时,装饰器需要传入的参数
        def out_warper(func): #这一层是传入函数名称
            def warper(*args,**kwargs):
                if intype == 'local':   #使用本地用户登录
                    user = input("Username:").strip()
                    passwd = input("Password:").strip()
                    if user == username and passwd == password:
                        print("\033[32;1m User has passed\033[0m")
                        timeformat = '%y-%m-%d, %X'   #显示登录的时间
                        timecuren = time.strftime(timeformat)
                        print("登录时间: %s" %timecuren)
                        res = func(*args,**kwargs)  #可以返回函数的使用值
                        print('the end')
                        return res
                    else:
                        #\033[31;1m格式是设置字体颜色的
                        exit("\033[31;1m Ivalid input\033[0m")
                elif intype == 'ldap':
                    print("目前暂不支持LDAP登录!")
            return warper
        return out_warper
    
    @loging() #相当于 home = loging(intype = 'local')
    def home():
        print("welecome to the home")
        return("welecome come to home next time")
    
    @loging(intype = 'ldap') #相当于 home = loging(intype = 'ldap')
    def bbs():
        print("welecome to the bbs")
        return("bbs come to next time")
    
    home()
    bbs()
    由于水平有限,以上讲述可能存在问题,希望多多更正
     


  • 相关阅读:
    [Noip2016]天天爱跑步
    [ioi2008]Island 岛屿
    [Poi2012]Rendezvous
    RCTF2019 next_php
    WinSocket编程笔记(五)
    PTA的Python练习题(二十一)
    WinSocket编程笔记(四)
    PTA的Python练习题(二十)
    WinSocket编程笔记(三)
    WinSocket编程笔记(二)
  • 原文地址:https://www.cnblogs.com/latencytime/p/10625114.html
Copyright © 2020-2023  润新知