装饰器(decorator)
一、定义
本质是函数,用来装饰其他函数,为其他函数添加附加功能
作用可以这么理解:程序已经运行了,但是需要增加功能
原则
①不能修改被装饰函数的源代码
②不能修改被装饰函数的调用方式
可以理解为装饰器对被装饰函数来说是透明的
装饰器实例
import time
def timmer(func):#装饰器
def wapper(*args, **kwargs):
start_time = time.time()
func()
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
return wapper
@timmer
def test1():#原函数
"sleep 3 秒并打印信息"
time.sleep(3)
print("in the test1")
test1()
二、实现装饰器的知识储备:
- 函数即变量
- 高阶函数
- 嵌套函数
高阶函数+嵌套函数–>装饰器
补充:python解释器的回收机制:
没有变量引用后回收内存
简单解释下,例如x=1,y=x 两次引用1,当x,y都不引用后解释器就回收1的内存空间,可以del删除x(只是删除1的引用,并未删除1),解释器检测到1没有饮用后自动回收。
补充:匿名函数
calc = lambda x:x*3 #calc的作用就是建立引用
print(calc(3))#9
如果没有=,则解释器直接回收掉匿名函数,类似变量(函数即变量)
1、高阶函数
满足下面两个条件之一:
- 把一个函数当做实参传给另一个函数
(装饰器中的作用:不修改被装饰函数的情况下实现附加功能)
- 返回值中包含函数名(装饰器中的作用:不修改函数的调用方式)
2、嵌套函数
在一个函数体内定义另一个函数
装饰器带参数,可同时给带参数和不带参数的函数增加相同功能
import time
def timer(func):
def deco(*args,**kwargs):#增加可变参数,灵活调用
start_time = time.time()
func(*args,**kwargs)
end_time = time.time()
print("the func run time is %s" %(end_time - start_time))
return deco
@timer # 相当于test1 = timer(test1)
def test1():
time.sleep(3)
print("in the test1")
@timer
def test2(name):
print("test2:",name)
test1()
test2("yanzhuang")
原函数带有返回值:
import time
def timer(func):
def deco(*args,**kwargs):#增加可变参数,灵活调用
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
print("the func run time is %s" %(end_time - start_time))
return res
return deco
@timer # 相当于test1 = timer(test1)
def test1():
print("in the test1")
return "from test1"
print(test1())
装饰器高级版
三层嵌套,增加了判断,可以给原函数选择性增加功能
user = "yanzhuang"
pwd = "abc123"
def auth(authtype):
print("auth:",authtype)
def out_wapper(func):
def wapper(*args, **kwargs):
if authtype == "local":
username = input("username:")
password = input("password:")
if user == username and pwd == password:
print("User passed authentication")
res = func(*args, **kwargs)
print("------after anthentication----")
return res
else:
exit("invalid username or password")
elif authtype == "ldop":
print("my mbp is coming")
return wapper
return out_wapper
@auth(authtype = "local")
def index():
print("welcome to index page")
@auth(authtype="local")
def home():
print("welcome to home page")
return "from home"
@auth(authtype = 'ldop')
def bbs():
print("welcome to bbs page")
index()
print(home())
bbs()