装饰器的作用是用一个新函数封装一个旧函数(在旧函数代码不变的情况下增加功能),这个新函数就叫做装饰器,一般为了简化装饰器会用语法糖**@新函数**来简化。
例子:
这是一段代码,但功能太少,要对这个进行增强,但又不能改变代码。
# 被修饰的函数
def hello():
return "hello world!"
1. 要增强hello()函数的功能,希望给返回加上HTML标签,但要求我们不得改变hello()函数原来的定义。
def makeitalic(fun):#makitalic传了一个新函数
def wrapped():#内部函数
return "<i>"+fun()+"</i>"#要加的新功能
return wrapped#返回的是wrapped函数功能
def hello():#对这个功能进行增强
return "hello world!"
#makeitalic里面传入了hello函数,然后内部函数fun()函数也就相当于hello函数了
hello_2=makeitalic(hello)
#打印新函数,返回的就是<i>hello world!</i>
print(hello_2())
<i>hello world!</i>
makeitalic就是一个装饰器(decorator),它封装了原函数hello,并返回了一个新函数,用于增强原函数的功能,并将其赋值给hello。
2. 使用装饰器提供的@语法糖(Syntactic Sugar),来简化上面的操作。
<i>hello world!</i>####使用@语法糖
def makeitalic(fun):
def wrapped():
return "<i>" + fun() + "</i>"
return wrapped
@makeitalic#使用了装饰器可以直接调用,不需要赋值了
def hello():
return "hello world"
print(hello())#使用了装饰器可以直接调用,不需要赋值了
<i>hello world</i>
3. 装饰器传参
修改装饰器的内部函数,使其与被修饰的函数参数量一致,内部函数调用被修饰函数时也应当包含参数。
def makeitalic(fun):
def wrapped(country):
return "<i>" + fun(country) + "</i>"
return wrapped
@makeitalic
def hello(country):
return "hello world {}".format(country)
print(hello("china"))
<i>hello world china</i>
4. 装饰器嵌套
装饰器可以定义嵌套多个,离函数定义最近的装饰器最先被调用
@decotator_one
@decorator_two
def fun():
pass
#格式如同下面的:
def fun():
pass
fun = decorator_one(decorator_two(fun))