装饰器 decorator
2023-04-24 本文已影响0人
午字横
闭包
# 闭包
def Print_A(a):
def Print_B(b):
print(a,b)
return Print_B
temp=Print_A("a")
temp("b")
闭包用到的核心其实就是:在一个函数中返回另外一个函数的引用,只不过这个被返回的函数中用到了其他函数中的变量而已。说到底就是 只要用一个变量指向某个函数代码块,就可以调用它
# 装饰器
def check_login(func):
print("1:---------------")
def check():
print('check')
func()
print("done:---------------")
print("2:---------------")
return check
@check_login
def login():
print('login')
login()
输出:
1:---------------
2:---------------
check
login
done:---------------
Process finished with exit code 0
当Python解释器对上述代码运行时,会从上到下解释代码,步骤如下:
遇到def check_login(func): 将check_login函数加载到内存
执行@check_login
没错, 从表面上看解释器仅仅会解释这两句代码,因为函数在 没有被调用之前其内部代码不会被执行。
从表面上看解释器着实会执行这两句,但是@check_login这一句代码里却有大文章, @xxx 是Python的一种语法糖(简单理解为令你很惊奇的功能)
其实就像相当于下边这两句:”
login=check_login(login)
login()
对带有参数的函数进行装饰
#对带有参数的函数进行装饰
def decroator_run(func):
def xxx(a,b):
print("xxx执行了")
func(a,b)
pass
return xxx
@decroator_run
def run(a,b):
print(a,b)
run("a","b")
通用装饰器
#通用装饰器
def decroator_run(func):
def xxx(*name):
print("xxx执行了")
func(name)
pass
return xxx
@decroator_run
def run(*name):
print(name)
run("a")
run("a","b")
对带有return的函数进行装饰
# 对带有return的函数进行装饰
def decroator_run(func):
def xxx():
temp= func()
pass
return temp
return xxx
@decroator_run
def run():
return "run done"
print(run())
s 多个装饰器对同一个函数进行装饰
# 多个装饰器对同一个函数进行装饰
def decroator_run_01(func):
def xxx():
return func()+"AAA"
pass
return xxx
def decroator_run_02(func):
def xxx():
return func()+"BBB"
pass
return xxx
@decroator_run_01
@decroator_run_02
def run():
return "run"
print(run())
输出:
runBBBAAA
Process finished with exit code 0
#装饰器带参数
# 多个装饰器对同一个函数进行装饰
def decroator_run_01(name):
def x(func):
def xxx():
print(name)
return func() + "AAA"
pass
return xxx
return x
@decroator_run_01(100)
def run():
return "run"
print(run())
用类当做装饰器
#用类当做装饰器
class Test(object):
def __init__(self, func):
print("---初始化---")
print("func name is %s" % func.__name__)
self.__func = func
def __call__(self):
print("---装饰器中的功能---")
self.__func()
@Test
def test():
print("----test---")
test() # 如果把这句话注释,重新运行程序,依然会看到"--初始化--"
- 当用Test来装作装饰器对test函数进行装饰的时候,首先会创建Test的实例对象
并且会把test这个函数名当做参数传递到init方法中
即在init方法中的属性__func指向了test指向的函数- test指向了用Test创建出来的实例对象
- 当在使用test()进行调用时,就相当于直接调用实例对象,因此会调用这个对象的call方法
- 为了能够在call方法中调用原来test指向的函数体,所以在init方法中就需要一个实例属性来保存这个函数体的引用
所以才有了self.__func = func这句代码,从而在调用call方法中能够调用到test之前的函数体
6. 总结
- 装饰器:能够快速将函数的指向修改,能够在不修改代码的前提下,给函数添加功能的方式
- 装饰器功能:给函数添加功能
- 特点:不修改原函数代码,还能添加功能;只能在原函数运行之前或者之后添加,不能在原函数运行一半时添加
- 实现过程:1. 将原函数的引用当做实参传递到闭包中 2. 修改原函数的指向为闭包中的内部函数
- 装饰器实际上用到了闭包,只不过在给外层函数传递参数时,传递的是需要被装饰的函数引用而已
- 装饰器还用到了引用,即在Python中,
a=xx
那么无论xx
是列表、字典还是对象,一定是a
指向它,而不是存储它
2023-04-25