装饰器的目的是为了扩展函数的功能,而不是修改函数本身。 它是一个非常强大的工具,它允许为现有的函数添加新的功能。
本文主要分享有两种装饰器:
一个函数可以被修饰为一个装饰器,使用 @
号。
示列代码:
@my_decorator
def my_function():
pass
看完上面的示例代码,我们再来看看这个函数是如何被修饰的。
为了理解装饰器模式,我们需要先强调下Python中一切都皆为对象。
函数也是一种对象,它可以被赋值给变量,还可以在另一个函数内定义,作为另一个函数的参数,或者从另一个函数返回。
装饰器是一个接受另一个函数作为参数的函数,它包装了函数的行为,并返回包装后的函数。所以装饰器的目的是为了扩展函数的功能,而不是修改函数本身。
练习下面代码:
def start_end_decorator(func):
def wrapper():
print("Start")
func()
print("End")
return wrapper
def print_name():
print("Alex")
print_name()
print()
# 使用装饰器得到一个新的函数
print_name_new = start_end_decorator(print_name)
print_name_new()
结果:
Alex
Start
Alex
End
解释:
上面的代码中定义了两个函数,其中print_name()
函数是一个普通函数,它的功能是打印Alex。
我们重点来看start_end_decorator()
函数:
func
是一个函数。wrapper(
)作为返回值。当然wrapper
就是一个名字而已,可以随意😊。wrapper()
首先打印出"Start",然后调用func()
,最后打印"End"。总起来看,start_end_decorator()
函数的是扩展了print_name()
函数的功能:
所以我们可以用start_end_decorator()
函数来修饰print_name()
函数,得到一个新的函数print_name_new
。
思考题,请写一个装饰器函数,来打印函数的执行时长。
上面的函数我们必须重新定义一个函数,这比较麻烦,所以Python提供了一种语法来定义装饰器。 它可以将修饰后函数赋值给自己,我们可以通过@
修饰我们的函数来实现相同的功能。
请练习下面代码:
def start_end_decorator(func):
def wrapper():
print("Start")
func()
print("End")
return wrapper
@start_end_decorator
def print_name():
print('Alex')
print_name()
结果:
Start
Alex
End
解释:
首先我们定义了一个装饰器start_end_decorator()
。 然后在定义新的函数print_name()
时,我们使用了@
装饰器。 从而print_name()
函数具备了新的功能!
是不是
@
非常简单,这也是真实工作中最常用的!!!
如果我们的函数有输入参数,上面的装饰器就无法实现,因为Python不允许装饰器接受参数。
那我们该怎么办呢?
我们可以在内部函数中使用 *args
和 **kwargs
来实现。
请尝试下面代码:
def start_end_decorator_2(func<