@[pyhton装饰器详解]
需要了解装饰器,就先要了解什么是高阶函数,什么是函数嵌套。装饰器其实就是高阶函数和函数嵌套的综合应用。
顾名思义,装饰器,就是起一个装饰的作用的方案。既不改变函数源代码、也不改变函数的调用方式,起到增加新功能的作用
如何判断一个函数它是不是装饰器,依据标准就是:不改变函数源代码、不改变函数的调用方式,又来修饰原函数的作用
一、高阶函数
简单的来讲,高阶函数就是将函数和变量联想起来,也可以这样说,函数即变量。下面我们来演示以下一个普通高阶函数的实例。
def fun1():
print("this is fun1")
def fun2():
print("this is fun2")
def fun(fun1,fun2):
fun1()
fun2()
fun(fun1,fun2)
我们来看一下运行结果
fun(fun1,fun2)的作用就是将fun1、fun2作为一个实参传递给fun(),在fun()内部运行fun1()和fun2()
这就是一个非常简单的高阶函数的例子。
二、函数嵌套
函数嵌套就是在一个函数的函数体里又定义了函数,可以是一个,也可以是多个。下面来看一下函数嵌套的实例。
def fun1():
print("this is fun1")
def fun2():
print("this is fun2")
def fun3():
print("this is fun3")
三、装饰器
此前说过,装饰器就是高阶函数和函数嵌套的综合应用。现在我们来看一个实例。
import time
def text1():
time.sleep(3)
print('in the text1')
def text2():
time.sleep(3)
print('in the text2')
text1()
text2()
运行结果:
此实例功能为调用text1()和text2(),在控制台上打印相应内容。如果想要给这两个函数新加一个功能,怎么办呢?这时候就要用到装饰器了。我们先来看代码:
import time
def timer(func):
def deco():
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is ",stop_time-start_time)
return deco
def text1():
time.sleep(3)
print('in the text1')
def text2():
time.sleep(3)
print('in the text2')
text1=timer(text1)
text1()
text2=timer(text2)
text2()
运行后发现
确实增加了一个函数功能(计算text1()和text2()的运行时间),是不是很神奇?既没有改变函数源代码、又没有改变函数调用方式,还增加了一个新功能。这就是装饰器的雏形,到底是怎么样实现的呢?再来看一下这个实例,是不是用到了函数嵌套还有高阶函数呢?如果还对函数嵌套还有高阶函数不了解的话,同志们可以去CSDN查看一下,在这里就不再多叙了。
再回过头来看看这段代码
text1=timer(text1)
text1()
text2=timer(text2)
text2()
要是有成千上万个函数需要装饰,是不是需要下面这样写呢
text3=timer(text3)
...
当然,你也可以这样写:
import time
def timer(func):
def deco():
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is ",stop_time-start_time)
return deco
@timer#语法糖 text1=timer(text1)
def text1():
time.sleep(3)
print('in the text1')
@timer
def text2():
time.sleep(3)
print('in the text2')
text1()
text2()
来看一下运行结果:
是不是又很神奇?和上一个运行结果一样呀!!!
在这里我们用了语法糖:@timer,其作用和text1=timer(text1)相同。是不是减少了很多工作量呢?只要想给哪个函数增加功能,就在这个函数前边加上@timer。
先不要急着开心!但是遇到带参的函数呢?就像这样子:
@timer
def text2(name):
time.sleep(3)
print('in the text2',name)
这该怎么办呢?话不多说,先来看解决办法:
import time
def timer(func):
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
stop_time=time.time()
print("the func run time is ",stop_time-start_time)
return deco
@timer#语法糖 text1=timer(text1)
def text1():
time.sleep(3)
print('in the text1')
@timer
def text2(name):
time.sleep(3)
print('in the text2',name)
text1()
text2('mumumax')
运行结果:
在这里,我们只需要将deco()传入参量,deco(*args,**kwargs)写法可以传多参,也可以不传参,是不是方便多了?
哈哈哈,是不是get一项新技能了呢?再接着get!!
在实际开发过程中,如某网站一个页面代表一个函数,现在需要给特定的一些页面来增添新功能(如增加用户验证),该怎么样实现呢?
先来看解决方法:
import time
user,passwd="mumumax","mumumax"
def auth(func):
def wrapper(*args,**kwargs):
usename=input("username:").strip()
password=input("password:").strip()
if usename==user and password==passwd:
print("pass the yanzheng")
res=func(*args,**kwargs)
else:
exit("验证失败")
return res
return wrapper
@auth
def index():
print("welcome to index page")
@auth
def home():
print("welcome to home page")
return "from home"
@auth
def bbs():
print("welcome to bbs page")
index()
home()
bbs()
index()为首页,home()为登陆页,bbs()为其他页。来看运行结果:
当我输入的username和password与数据库中的相匹配时,我才可以访问index()、home()、bbs(),负责会“验证失败”。
python的基本解释器就讲解到这里,如果掌握了这些东西,99%的解释器原理你都已经掌握了,剩下的1%交给实战吧,如果对我的文章感兴趣,请为我点一个赞,如果有python的知识需要了解或探讨,可以加本人微信:cuiliang1666457052