1. 装饰器简介
在使用Python开发时,经常需要添加额外的功能,比如日志记录、性能分析、缓存等,此时我们可以使用装饰器来为这些函数添加新的功能而不改变它们的原有逻辑。在Python中,装饰器本质上是一个Python函数,它可以接受另一个函数或类作为输入,并对其进行修改,最终返回修改后的函数或类。
def decorator(func):
def wrapper():
# 添加新功能
return func()
return wrapper
@decorator
def func():
pass
这里定义了一个装饰器函数decorator
,它接受一个函数参数func
,并返回一个函数wrapper
,wrapper
函数就是我们添加了新功能后的函数。在func
函数之前加上@decorator
,就可以将decorator
装饰器应用于func
函数。
2. 咖啡加糖装饰器示例
2.1 实现
下面我们来实现一个咖啡加糖的装饰器,将原有的咖啡加上糖。
def add_sugar(func):
def wrapper():
ret = func()
return ret + ' + sugar'
return wrapper
@add_sugar
def coffee():
return 'coffee'
print(coffee()) # 输出 'coffee + sugar'
这里定义了一个装饰器函数add_sugar
,它接收一个函数func
作为参数,并返回一个新的函数wrapper
。wrapper
函数调用原函数func
并对其返回值进行修改,最后返回修改后的值。
在这个例子中,我们定义了一个咖啡函数coffee
,并将add_sugar
装饰器应用于它。当我们调用coffee
函数时,实际上执行的是wrapper
函数,该函数会先调用原函数coffee
,然后将返回值加上糖。
2.2 装饰器的嵌套
装饰器可以进行嵌套,即一个装饰器可以接受另一个装饰器作为参数。下面我们来实现一个咖啡加糖加奶的装饰器,它可以接受add_sugar
装饰器作为参数。
def add_milk(func):
def wrapper():
ret = func()
return ret + ' + milk'
return wrapper
@add_milk
@add_sugar
def coffee():
return 'coffee'
print(coffee()) # 输出 'coffee + sugar + milk'
在这个例子中,我们定义了一个add_milk
装饰器和coffee
函数。将add_sugar
装饰器应用于coffee
函数之前,即可实现咖啡加糖加奶的功能。
3. 带参数的装饰器
我们可以定义一个带参数的装饰器,让装饰器对不同的函数产生不同的行为。下面我们来实现一个可以接受参数的装饰器,它可以指定咖啡加多少糖。
def add_sugar(sugar):
def decorator(func):
def wrapper():
ret = func()
return ret + ' + {}g sugar'.format(sugar)
return wrapper
return decorator
@add_sugar(20)
def coffee():
return 'coffee'
print(coffee()) # 输出 'coffee + 20g sugar'
我们定义了一个add_sugar
函数,它接收一个参数sugar
,并返回一个装饰器函数decorator
。这里的decorator
装饰器函数实际上就是一个没有参数的装饰器,其作用和之前的例子一样。在这里,我们将接收到的sugar
参数传递给wrapper
函数,作为糖的数量。
在使用带参数的装饰器时,我们需要将装饰器函数和参数分开写,类似于@decorator(args)
的形式。
4. 总结
装饰器是Python中一个非常强大的功能,它可以为函数添加额外的行为,让我们可以在不改变函数原有逻辑的情况下添加新功能。在实际开发中,我们经常会使用装饰器来进行日志记录、性能分析、缓存等操作。同时,装饰器也可以进行嵌套和带参数的操作,让我们可以更加灵活地使用装饰器。
参考代码:
def add_sugar(func):
def wrapper():
ret = func()
return ret + ' + sugar'
return wrapper
@add_sugar
def coffee():
return 'coffee'
print(coffee()) # 输出 'coffee + sugar'
def add_milk(func):
def wrapper():
ret = func()
return ret + ' + milk'
return wrapper
@add_milk
@add_sugar
def coffee():
return 'coffee'
print(coffee()) # 输出 'coffee + sugar + milk'
def add_sugar(sugar):
def decorator(func):
def wrapper():
ret = func()
return ret + ' + {}g sugar'.format(sugar)
return wrapper
return decorator
@add_sugar(20)
def coffee():
return 'coffee'
print(coffee()) # 输出 'coffee + 20g sugar'