要理解python的装饰器的前提是要了解python的函数闭包,什么是函数闭包呢?简单来说就是函数里定义和调用函数。
这是一个两层装饰的装饰器
def decorator1(fun):
print('decorator1')
def in_decorator1():
print('in_decorator1')
def inner1():
print('inner1')
def inner2():
print('inner2')
return fun
return inner2()
return inner1()
return in_decorator1()
def decorator2(fun):
print('decorator2')
def in_decorator2():
print('in_decorator2')
def inner2_1():
print('inner2_1')
def inner2_2():
print('inner2_2')
return fun
return inner2_2()
return inner2_1()
return in_decorator2()
@decorator2
@decorator1
def fun():
print('in fun')
if __name__ == "__main__":
fun()
执行结果如下
decorator1
in_decorator1
inner1
inner2
decorator2
in_decorator2
inner2_1
inner2_2
in fun
在没有理解python的函数闭包之前我是不能理解上面那段代码的执行过程的,先来看看python的闭包,
这段代码很简单,输出变量a的值10。
def fun():
a = 10
print(a)
if __name__ == "__main__":
fun()
我们知道python中在函数中定义的变量只能在函数中使用而不会被函数外的其他方法调用。
def fun():
a = 10
print(a)
print(a)
那么在函数中定义函数又是怎么样的呢?
这段代码会输出变量a的值,这说明了在函数fun()中定义的变量可以在fun()函数中的函数in_fun()中使用。
def fun():
a = 10
def in_fun():
print(a)
return in_fun()
if __name__ == "__main__":
fun()
如果改成下面这样会看不到执行结果,仔细一看会发现,调用fun()的时候,in_fun()这个函数并没被调用,只是被定义。
def fun():
a = 10
def in_fun():
print(a)
if __name__ == "__main__":
fun()
所以我们必须在函数fun()调用时在fun()函数中调用其子函数,否则就不会执行子函数而仅仅只是被定义。
def fun():
a = 10
def in_fun():
print(a)
in_fun()
if __name__ == "__main__":
fun()
在fun()中定义的变量,fun()的子函数都能使用这个变量,就像在类中定义一个变量,其子类、子类的子类都能使用这个变量一样。
def fun():
a = 10
def in_fun1():
b = 20
def in_fun2():
print(a)
print(b)
in_fun2()
in_fun1()
if __name__ == "__main__":
fun()
一个完整的闭包就是函数中定义变量并且在函数中定义函数,在函数中使用函数,层层嵌套,使无限套娃成为了可能,但是要记住套娃有风险,必须要在上一层完成对下一层的调用,下面这段代码由于直接在fun()中调用in_fun2(),没有调用in_fun1(),所以调用的是一个没有定义的in_fun2()。
def fun():
a = 10
def in_fun1():
b = 20
def in_fun2():
c = 30
print(a)
print(b)
in_fun2()
if __name__ == "__main__":
fun()
只要上一层完成对下一层函数的调用,就可以无限套娃了,这就是函数的闭包。
def fun():
a = 10
def in_fun1():
b = 20
def in_fun2():
c = 30
def in_fun3():
d = 40
def in_fun4():
e = 50
print(a+b+c+d+e)
return 0
return in_fun4()
return in_fun3()
return in_fun2()
return in_fun1()
if __name__ == "__main__":
fun()
装饰器就是为了在不改变原函数的基础上扩展程序而出现的python语法糖,菜鸟教程中写得非常好,通俗易懂。
以一层的装饰器来说,主要注意的是最里面的一层,return fun
返回的是函数的引用而不是返回函数的调用,因为我们的最终的目的不是执行fun()这个函数,而是在执行这个函数之前对其做装饰。
def decorator1(fun):
print('decorator1')
def in_decorator1():
print('in_decorator1')
def inner1():
print('inner1')
def inner2():
print('inner2')
return fun
return inner2()
return inner1()
return in_decorator1()
@decorator1
def fun():
print('in fun')
if __name__ == "__main__":
fun()