装饰器
就是为其他函数添加新功能的函数,装饰器本身就是高阶函数,嵌套函数以及闭包的综合应用
原则
- 不修改被装饰函数的源代码(开放封闭原则)
- 为被装饰函数添加新功能后,不修改被修饰函数的调用方式
高阶函数
满足以下两点任意一个的都叫做高阶函数
- 函数接收的参数是一个函数名
- 函数的返回值是一个函数名
#######该函数返回的是函数,那么算是高阶函数#######
>>>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('产品经理')