在说装饰器的时候先说一个小的知识点
当定义了相同函数名的函数,在调用的时候回执行最后一个
执行的结果为2,第一次的函数被覆盖了。
装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以本次我们来说一下python中的装饰器
在开发的过程中我们要遵守开放封闭的原则
封闭:已实现功能的代码块
开放:对扩展开放
所以当我们想要对已经实现的功能就行修改的时候,只能对其进行扩展,所以我们就引入了装饰器。下面我们以代码为例,讲解装饰器。
def w1():
print("----正在验证权限---")
def f1():
print('----f1----')
def f2():
print('----f2----')
如果想要让f1()和f2()分别调用w1(),但是有不能修改f1()和f2()的代码,该怎么办呢? 这时候我们我们就用到了python中的语法糖。
def w1(func):
def inner():
print("----正在验证权限---")
func()
return inner
@w1
def f1():
print('----f1----')
@w1
def f2():
print('----f2----')
f1()
f2()
执行的结果为这样就达到了我们预期的效果,也遵守了开放封闭原则。
下面我们就来一步一步的说说装饰器的工作原理
首先我们需要把w1()改造一下
def w1():
def inner():
print("----正在验证权限---")
return inner
# 现在w1是一个闭包函数,所以innerFunc指向了inner
innerFunc = w1()
def w1(func):
def inner():
print("----正在验证权限---")
# 如果func指向了f1,再innerFunc()的时候就会执行f1()
func()
return inner
# 现在w1是一个闭包函数,所以innerFunc指向了inner
innerFunc = w1()
到了这里你会想当初不是说调用f1() 就执行w1()么?怎么又出来个innerFunc()呢?看官别着急,听我慢慢说
innerFunc = w1() 这个时候我们在调用的时候就需要传一个参数了,当然你猜对了,就是把f1传入。
w1(f1)有一个返回值,现在我们是用的innerFunc来接收的,但如果我们把这个变量名换成f1呢?这样是不是就能达到我们想要的结果了?
说一下这张图的原理:
1.当执行f1 = w1()的时候 先执行等号右边的
2.执行w1()的时候把f1传进去了,所以在w1中定义的func的引用指向了f1的引用
3.当执行到了inner()的时候,在w1中返回(return inner)的地址 让f1接收了,所以f1的引用现在指向了inner的引用
4.当我们执行f1()的时候,f1()指向了inner,所以就执行inner()
当执行到func()的时候 ,func()指向f1(),所以func()中的内容变成了f1(). 实际上就调用f1了,当我们在调用f1()的时候其实功能已经变了,已经把w1()的功能加进去了
总结:
需要一个闭包函数,传入的必须是一个函数对象。