装饰器
定义
装饰器本身是一个可调用对象,接收一个函数作为参数,然后将其返回或替换成另一个函数或可调用对象。可以理解成,原来那是一堵白墙,经过了一层装饰,这层装饰可能是漆也可能把墙掏空镶进一层黄金变得金光闪闪,最后呈现在你眼前的就是装饰后的样子。
可以把它完全当成常规函数来调用,其参数是另一个函数。装饰器有两大特征,一是能把被装饰的函数替换成其他函数,二是装饰器在加载函数时立即执行。
def read_oil(func):
print("ready to paint!")
def red_wall_func():
print("red wall")
return red_wall_func
@read_oil
def wall():
print("wall!")
if __name__=="__main__":
print("start painting")
wall()
输出
ready to paint!
start painting
red wall
可以看出,装饰器 red_oil
将函数 wall
替换成了另一个函数,就好比在原来的墙上刷了一层红漆。而装饰器在被装饰的函数被定义时立即执行,而被装饰的函数在运行的时候才执行,这也是导入时和运行时的区别。
函数中变量的作用范围
red_paint="red oil"
def wall(paint):
print(paint)
global red_paint
print(red_paint)
if __name__ == '__main__':
wall("yelloow oil")
输出
yelloow oil
red oil
nonlocal声明
nonlocal
声明,作用是将变量标记为自由变量,也就意味着我们可以对做了 nonlocal
声明的变量进行修改
def wall():
nums=0
oils=[]
def paint_wall(color):
nonlocal nums
nums +=1
oils.append(color)
print("Paint wall by color:"+color)
print("Paint wall {} times".format(nums))
return oils
return paint_wall
if __name__ == '__main__':
white_wall=wall()
white_wall("red")
white_wall("yellow")
输出
Paint wall by color:red
Paint wall 1 times
Paint wall by color:yellow
Paint wall 2 times
带参数的装饰器
既然装饰器本质上就是一个函数,那装饰器也可以传参。那么具体应该怎么做呢?在 Python 中需要建立一个装饰器工厂函数,把参数传给它,再返回一个装饰器,然后应用到要装饰的函数上。