当我们在讨论装饰器的时候,装饰器在讨论什么?
让我们逐步去揭开它的面纱
一.嵌套函数的函数
python中的函数大家都了解,以def关键字命名,那嵌套函数的函数顾名思义def定义的内容里面还包裹一个函数
def test_b():
print("2")
def test_a():
print ("1")
test_b()
test_a()
>>>>1
>>>>2
二.函数的闭包
我们已经知道了函数的嵌套,那函数的闭包,就是在def定义的函数里面,再使用一个def定义函数,return的值为嵌套的函数
def test_a(a,b):
print(1)
def test_b():
print(2)
return a + b
return test_b
print(test_a(2,3)())
>>>>1
>>>>2
>>>>5
def test_a():
print(1)
def test_b(c):
print(2)
return c
return test_b
print(test_a()(4))
>>>>1
>>>>2
>>>>4
根据上面例子可以看出闭包的几个特点
1.两个嵌套的def函数
2.外部函数return的值为内部的函数名字
3.内部的嵌套函数需要return值,否则后续外部调用,会return的值为None
4.在函数调用时,需要添加括号()
5.函数的传参,外部函数参数传入第一个(),内部函数参数传入第二个括号()
6.内部函数可以调用外部函数的局部变量
三.装饰器
装饰器简单来说就是,函数闭包的另类应用
最大区别还是参数的范围
一般的闭包传递的实参都为具体的值,但是对于装饰器来说,更多的是为方法或者类服务的,传入参数为方法或者类,重要的是调用外部方法的逻辑和局部变量,对原有的函数功能进行扩展
举2个例子
def test_a(func):
print("this is test_a")
def test_b():
func()
print("this is test_b")
return test_b
@test_a
def test_c():
print("this is test_c")
test_c()
>>>>this is test_a
>>>>this is test_b
>>>>this is test_c
def complex_test(test_param):
'''
:param:参数
:return:
'''
print("this is a test")
def test_func(func):
print("this is a func")
def func_param(*args):
func(test_param,*args)
return func_param
return test_func
上面就是稍微复杂点函数装饰器的例子,对原有的函数功能进行了扩展,我们现在逐层分析,需要注意第一层中对装饰器的传参是需要传给下面需要装饰的函数的(切记不要传入函数),第二层中传入的参数就是函数,第三层才是对函数功能进行逻辑扩展,且利用上了最外层传给装饰器的变量。
需要注意的是。里层函数需要的参数数量,在调用该函数时,需要一个形参来接收装饰器给的参数
如
@complex_test("这是一个测试参数")
def testcast(test_param)
print(test_param,"test_decorate")
testcast()
>>>>this is a test
>>>>this is a func
>>>>这是一个测试参数 test_decorate
当然你也可以不传入参数,对函数处理后,抛出你想要的数据/函数也可以,但是需要注意的时,想让装饰器返回什么值,被装饰函数就需要一个对应形参接收
def complex_test(test_param):
'''
:param:参数
:return:
'''
print("this is a test")
def test_func(func):
print("this is a func")
def func_param(*args):
func(test_param,"test_a",*args)
return func_param
return test_func
@complex_test("这是一个测试参数")
def testcast(test_param,reception_param):
print(test_param,"test_decorate",reception_param)
testcast()
>>>>this is a test
>>>>this is a func
>>>>这是一个测试参数 test_decorate,test_a
以上就是函数装饰器的基本原理以及项目过程中,可能遇到情况,装饰器的好处就是
1.遵循的编码中的代码不能随意修改
2.适用多种需求的切换
当时这还只是函数装饰器,还有更为复杂的类装饰器,原理是类似的,就是适用性更广