装饰器-----本质是函数,功能是为其他函数添加附加功能
原则:1.不修改被装饰函数的源代码
2.不修改被装饰函数的调用方式
装饰器=高阶函数+函数嵌套+闭包
闭包——闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b,def timer(func):
def wrapper(): print(func) func() return# encoding:utf-8
例子1
# encoding:utf-8 import time def timer(fun): def wrapper(): start=time.time() fun() stop=time.time() print("运行时间%s"%(stop-start)) return wrapper @timer #等价于test=timer(test) def test(): time.sleep(3) print("运行完毕") #test=timer(test) test()
例子2.在例子1中,如果test()有返回值,不会输出
# encoding:utf-8 import time def timer(fun): def wrapper(): start=time.time() result=fun() #改动1 stop=time.time() print("运行时间%s"%(stop-start)) return result #改动2 return wrapper @timer #等价于test=timer(test) def test(): time.sleep(3) print("运行完毕") return "这是test的结果" #test=timer(test) r=test() print(r)
例子3.被修饰的函数有参数
准备知识——解压序列(一一对应)
a,b,c=(1,2,3) print(a) print(b) print(c)
# encoding:utf-8
import time
def timer(func):
def wrapper(*args,**kwargs): #可变参数*args和关键字参数**kwargs
start_time=time.time()
res=func(*args,**kwargs) #res接受func的返回值
stop_time=time.time()
print('运行时间为%s'%(stop_time-start_time))
return res
return wrapper #内部函数调用
@timer #test=timmer(test),第一个test是用来接受函数的变量(test=wrapper),第二个是函数名
def test(name,age,gender):
time.sleep(3)
print('test运行结束')
return '这是test返回值'
res=test("1",3,'man')
print(res)
python中交换
a=2 b=1 a,b=b,a print(a,b)
京东登陆模拟
# encoding:utf-8 user_dic={'username':None,'log':False} #用状态保存登陆状态 def auth_func(func): def wrapper(*args,**kwards): if user_dic['username'] and user_dic['login']: res=func(*args,**kwards) return res username=input('用户名:').strip() #除去空格或者换行符 passwd=input('密码:').strip() if username=='小明'and passwd=='123456': user_dic['username']=username user_dic['login']=True res=func(*args,**kwards) return res else: print('用户名或者密码错误') return wrapper @auth_func def index(): print('欢迎到来') @auth_func def home(name): print('欢迎%s到来'%(name)) @auth_func def shopping(name): print('欢迎%s到来'%(name)) index() home('小明') shopping('小明')