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('产品经理')

posted @ 2019-03-30 19:01  Mingle_Yuan  阅读(178)  评论(0编辑  收藏  举报