装饰器
-
定义
本质是函数,用来装饰其他函数,为其他函数添加附加功能。
- 原则
不能修改被装饰函数的源代码
不能修改被装饰的函数的调用方式 - 应用的知识
高阶函数
嵌套函数 - 嵌套函数
def a(): print("aaaa") def b(): # 在函数a中 定义函数b print("bbbb") # 函数b为嵌套函数
- 原则
-
装饰器
- 基础装饰器
# -*- encoding: utf-8 -*- # !@Author : Merky import time def timer(func): # func = test_1 test_1的内存地址赋值给了func def deco(): start_time = time.time() func() stop_time = time.time() print("the func run time is %s" % (stop_time-start_time)) return deco # 返回deco的地址 @timer # test_1 = timer(test_1) => test_1 = deco 把 deco的物理地址赋值给了test_1 def test_1(): time.sleep(1) print("in the test1") test_1()
- 带参数装饰器
# -*- encoding: utf-8 -*- # !@Author : Merky import time def timer(func): # func = test_1 test_1的内存地址赋值给了func def deco(*args,**kwargs): start_time = time.time() func(*args,**kwargs) # 此处调用func实际是调用了被装饰的函数 stop_time = time.time() print("the func run time is %s" % (stop_time-start_time)) return deco @timer # test_1 = timer(test_1) => test_1 = deco 把 deco的物理地址赋值给了test_1 def test_1(name): time.sleep(1) print(name) def aa_1(): time.sleep(0.5) print("in the aa_1") test_1("XIao") # 传递参数问题 aa_1()
- 当被修饰函数有返回值时
# -*- encoding: utf-8 -*- # !@Author : Merky user, passw = "admin", "123456" def auth(func): # func = home def wrapper(*args, **kwargs): username = input("username:").strip() password = input("password:").strip() if user == username and passw == password: print("\033[32;1mUser has passed authentication \033[0m") return func(*args, **kwargs) # func执行的就是原来的被装饰的函数,其执行结果与原函数执行结果相同,故返回值在这里返回 else: exit("\033[31;1mInvalid \033[0m") return wrapper def index(): print("welcome to index page!") @auth # home = wrapper def home(): print("welcome to home page!") return "home has a return!" # 此处的返回结果 为装饰器中 func()函数的执行结果 @auth def bbs(): print("welcome to bbs page!") index() print(home()) bbs()
实质上:
装饰器就是在新定义的高阶嵌套函数中,将需要装饰的函数的物理地址作为一个函数参数传给装饰器,在新函数中新功能的恰当位置,调用这个参数,实际上是调用了原来被装饰的函数。从而在不修改原来函数的源代码和调用方式的基础上达到增添新功能的效果。基础装饰器例子中即把test_1地址赋值给 func,把deco地址赋值给test_1,
调用func时,实现的被装饰原函数的调用,执行deco时,实现了把参数传入修饰器中的功能。