• Python装饰器


    装饰器

    就是为其他函数添加新功能的函数,装饰器本身就是高阶函数,嵌套函数以及闭包的综合应用

    原则

    • 不修改被装饰函数的源代码(开放封闭原则)
    • 为被装饰函数添加新功能后,不修改被修饰函数的调用方式

    高阶函数

    满足以下两点任意一个的都叫做高阶函数

    • 函数接收的参数是一个函数名
    • 函数的返回值是一个函数名
    #######该函数返回的是函数,那么算是高阶函数#######
    >>>def test_func():
     	 print("come from test_func")
     	 def test_func_1():
     		 print("come from test_func_1")
     		 def test_func_2():
     			 print("come from test_func_2")
    		 return test_func_2
    	 return test_func_1
    
    >>>print(id(test_func))
    >>>test_func()()()
    
    2417040908360    ##函数既是变量,返回一个内存地址,在它后面加()就执行函数了
    come from test_func
    come from test_func_1   
    come from test_func_2
    
    ############该函数传入的是函数,也是高阶函数###########
    >>>def func():
    	 print("I love you!")
    
    >>>import time
    >>>def test_time(func):
    	 start_time = time.time()
    	 func()
    	 stop_time = time.time()
    	 run_time = start_time - stop_time
    	 print("It run %s" %run_time)
    >>>test_time(func)   ##但是其改变了调用方式,所以并不能称之为装饰器
    I love you!
    It run 0.0
    

    嵌套函数

    一个函数里面嵌套一个运行的函数

    >>>def fathrt_func():
    	 print("I am from fathrt_func")
    	 def son_func():
    		 print("I am from son_func")
    		 def grandson_func():
    			 print("I am from grandson_func")
    		 grandson_func()   
    	 son_func()
    
    >>>fathrt_func()
    
    I am from fathrt_func
    I am from son_func
    I am from grandson_func
    

    装饰器代码实例

    测试软件花费时间

    >>>import time
    >>>def test_run_time(func):
    	 def swrapper(*args, **kwargs):	##使用*args和**kwargs这样,原函数可以传入任意参数
    		 start_time = time.time()       
    		 res = func(*args, **kwargs)      ##这里的传入参数即是swrapper()嵌套函数里面的,而res即是为了原函数里面有返回值
    		 stop_time = time.time()       
    		 run_time = stop_time - start_time
    		 print("It costs %s seconds" %run_time)
    		 return res      ##返回原函数的返回值
    	 return swrapper    ##返回嵌套函数的内存地址
    	
    >>>@test_run_time		##该处等同于在func_test_1 = test_run_time(func_test_1)
    >>>def func_test_1(name, age, gender):
    	 time.sleep(2)
    	 print("I am {0}, {1} years old, a {2}".format(name, age, gender))
    	 return "There are my all informations!"
    
    >>>@test_run_time	
    >>>def func_test_2(name, age, hometown):
    	 time.sleep(2)
    	 print("I am {0}, {1} years old, come from {2}".format(name, age, hometown))
    	 return "There are my all informations!"
    	
    func_test_1("Hermaeus", 18, "male")
    func_test_2("YuanMing", 19, "MeiShan")
    

    带有参数验证功能的装饰器

    user_list=[
        {'name':'alex','passwd':'123'},
        {'name':'linhaifeng','passwd':'123'},
        {'name':'wupeiqi','passwd':'123'},
        {'name':'yuanhao','passwd':'123'},
    ]
    current_dic={'username':None,'login':False}
    
    def auth(auth_type='filedb'):   ##再嵌套一层可以传递一个参数
        def auth_func(func):
            def wrapper(*args,**kwargs):
                print('认证类型是',auth_type)
                if auth_type == 'filedb':
                    if current_dic['username'] and current_dic['login']:
                        res = func(*args, **kwargs)
                        return res
                    username=input('用户名:').strip()
                    passwd=input('密码:').strip()
                    for user_dic in user_list:
                        if username == user_dic['name'] and passwd == user_dic['passwd']:
                            current_dic['username']=username
                            current_dic['login']=True
                            res = func(*args, **kwargs)
                            return res
                    else:
                        print('用户名或者密码错误')
                elif auth_type == 'ldap':
                    print('鬼才特么会玩')
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('鬼才知道你用的什么认证方式')
                    res = func(*args, **kwargs)
                    return res
    
            return wrapper
        return auth_func
    
    @auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type  --->index=auth_func(index)
    def index():
        print('欢迎来到京东主页')
    
    @auth(auth_type='ldap')
    def home(name):
        print('欢迎回家%s' %name)
    
    @auth(auth_type='sssssss')
    def shopping_car(name):
        print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃'))
    shopping_car('产品经理')
    
    
  • 相关阅读:
    用DECODE进行排序
    linux下批量替换文件内容
    Linux下chkconfig命令详解
    linux 命令参数列表过长以及find用法
    参数上使用自定义注解在aop中无法获取到该参数
    AOP
    AOP aspect XML 配置
    AOP前世与今生,aspect
    ETL工具之——kettle使用简介
    ETL工具之kittle使用案例整理
  • 原文地址:https://www.cnblogs.com/MingleYuan/p/10628516.html
Copyright © 2020-2023  润新知