一 什么是装饰器
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器定义:本质就是函数,功能是为其他函数添加新功能 #装饰器本身就是函数,被装饰的也是函数。
为什么要用装饰器:
1.不修改被装饰函数的源代码(开放封闭原则);
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式。
代码上线后,就是为了尽量避免修改,不修改原函数的源代码和调用方式。 # 函数及定义和使用。
装饰器语法:
在被装饰上的正上方写一个@,它会把@这一行下面这一行的函数传递到函数里,再重新赋值给index。
func就是index函数,print(func)返回得是index内存地址。
二 装饰器需要遵循的原则
1.不修改被装饰函数的源代码(开放封闭原则)
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式
(1)无参装饰器:
不用传参数来使用装饰器。
以下的操作是为函数foo来增加新的计时功能:不改变原函数的代码和调用方式
import time #调用time模块 def timmer(func): #装饰器timmer,将函数foo的函数名为参数传给timmer def wrapper():#嵌套函数 start_time = time.time()#开始时间 func() #func=函数foo的内存地址加括号函数是可以直接被调用的 stop_time = time.time() #结束时间 print("函数运行的时间是%s"%(stop_time-start_time)) return wrapper #返回wrapperde 值 @timmer #装饰器的语法@+装饰器名,foo = timmer(foo) def foo(): #定义的一个无参函数 time.sleep(2) #使程序睡眠2s print("welcome to beijing") foo() #调用foo函数 ---------------------以下是输出结果---------------------- welcome to beijing 函数运行的时间是2.0
(2)
要传参数来使用装饰器。
以下的操作是为函数my_max来增加新的计时功能:不改变原函数的代码和调用方式
import time #调用time模块 def timmer(func): #嵌套函数 def wrapper(*args,**kwargs):#接收参数 start_time = time.time() #开始计时 func(*args,**kwargs) #通过内存地址加括号里接收的参数来调用函数 stop_time = time.time() #结束计时 print("函数的运行时间是%s"%(stop_time-start_time)) return wrapper #返回wrapper的值 @timmer #my_max=timmer(my_max)#为my_max这个函数增加计时功能 def my_max(x,y): #比较两个数的大小 time.sleep(3) #睡眠3s,方便实验效果 res = x if x > y else y #判断x与y的大小 print("from the my_max,the max is %s"%res) my_max(1,2) #调用函数并按位置传参 ---------------------以下是输出结果----------------------- from the my_max,the max is 2 函数的运行时间是3.0
三 实现装饰器知识储备
装饰器=高阶函数+函数嵌套+闭包
四 高阶函数
高阶函数定义:
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
3.满足上述条件任意一个,都可称之为高阶函数
def foo(): print('我的函数名作为参数传给高阶函数') def gao_jie1(func): print('我就是高阶函数1,我接收的参数名是%s' %func) func() def gao_jie2(func): print('我就是高阶函数2,我的返回值是%s' %func) return func gao_jie1(foo) gao_jie2(foo) 高阶函数示范
#高阶函数应用1:把函数当做参数传给高阶函数 import time def foo(): print('from the foo') def timmer(func): start_time=time.time() func() stop_time=time.time() print('函数%s 运行时间是%s' %(func,stop_time-start_time)) timmer(foo) #总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式 把函数当做参数传给高阶函数
#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名 import time def foo(): print('from the foo') def timmer(func): start_time=time.time() return func stop_time=time.time() print('函数%s 运行时间是%s' %(func,stop_time-start_time)) foo=timmer(foo) foo() #总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能 函数返回值是函数名
高阶函数总结
1.函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
2.函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
五 函数嵌套
def father(name): print('from father %s' %name) def son(): print('from son') def grandson(): print('from grandson') grandson() son() father('林海峰')
六 闭包
''' 闭包:在一个作用域里放入定义变量,相当于打了一个包 ''' def father(name): def son(): # name='alex' print('我爸爸是 [%s]' %name) def grandson(): # name='wupeiqi' print('我爷爷是 [%s]' %name) grandson() son() father('林海峰')
七 无参装饰器
装饰器举例
无参装饰器1运行结果
无参装饰器2无参装饰器3
有参装饰器
#为什么要用装饰器及开放封闭原则 #什么是装饰器 # import time # def timmer(func): # def wrapper(*args,**kwargs): # start=time.time() # res=func(*args,**kwargs) # stop=time.time() # print('run time is %s ' %(stop-start)) # return wrapper # # # @timmer # def index(): # time.sleep(3) # print('welcome to oldboy') # # index() #装饰器 # import time # # @名字 #home=名字(home) # def home(): # time.sleep(3) # print('welcome to oldboy') # # index() # def get(url): # def index(): # return urlopen(url).read() # return index import time def timmer(func): #func=home def wrapper(): # print(func) start_time=time.time() func() stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return wrapper # index=timmer(index) @timmer def index(): time.sleep(3) print('welcome to oldboy') @timmer def home(name): time.sleep(2) print('welcome to %s home page' %name) # def my_max(x,y): # print('from my_max func') # return x+y # index() #--=--->wrapper() home('dragon')
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() func(*args,**kwargs) #home(name) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return wrapper @timmer #home=timmer(home) def home(name): time.sleep(2) print('welcome to %s home page' %name) @timmer #auth=timmer(auth) def auth(name,password): print(name,password) @timmer def tell(): print('-=----------') home('dragon') #wrapper('dragon') auth('egon','123') #wrapper('egon','123') tell()
import time def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) #my_max(1,2) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper @timmer def my_max(x,y): print('my_max function') res=x if x > y else y return res res=my_max(1,2) #res=wrapper(1,2) print('=====>',res)
def auth2(auth_type): def auth(func): # print(auth_type) def wrapper(*args,**kwargs): if auth_type == 'file': name=input('username: ') password=input('password: ') if name == 'zhejiangF4' and password == 'sb945': print('auth successfull') res=func(*args,**kwargs) return res else: print('auth error') elif auth_type == 'sql': print('还他妈不会玩') return wrapper return auth @auth2(auth_type='sql') #@auth #index=auth(index) def index(): print('welcome to inex page') # @auth # def home(): # print('welcome to home page') index()
def auth2(auth_type): #1 #3 def auth(func): #4 #6 def wrapper(*args,**kwargs): #7 #10 if auth_type == 'file': #11 name=input('username: ') password=input('password: ') if name == 'zhejiangF4' and password == 'sb945': print('auth successfull') res=func(*args,**kwargs) return res else: print('auth error') elif auth_type == 'sql': #12 print('还他妈不会玩') #13 return wrapper #8 return auth #5 @auth2(auth_type='sql') #2 def index(): print('welcome to inex page') # @auth # def home(): # print('welcome to home page') index() #9
# @aaa # def func(): # pass # # # func=aaa(func) # @ccc # @bbb # @aaa # def func(): # pass # # func=ccc(bbb(aaa(func))) # # @ccc('c') # @bbb('b') # @aaa('a') # def func(): # pass # # func=ccc('c')(bbb('b')(aaa('a')(func)))
import time current_login={'name':None,'login':False} def timmer(func): def wrapper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) #my_max(1,2) stop_time=time.time() print('run time is %s' %(stop_time-start_time)) return res return wrapper def auth2(auth_type='file'): def auth(func): # print(auth_type) def wrapper(*args,**kwargs): if current_login['name'] and current_login['login']: res=func(*args,**kwargs) return res if auth_type == 'file': name=input('username: ') password=input('password: ') if name == 'zhejiangF4' and password == 'sb945': print('auth successfull') res=func(*args,**kwargs) current_login['name']=name current_login['login']=True return res else: print('auth error') elif auth_type == 'sql': print('还他妈不会玩') return wrapper return auth @timmer @auth2(auth_type='file') #@auth #index=auth(index) def index(): print('welcome to inex page') @auth2() def home(): print('welcome to home page') #调用阶段 index() home()