装饰器是Python中一个非常有趣的特性,它允许程序员在不改变现有代码结构的情况下,对函数或方法进行扩展。简单来说,装饰器就是一个接受函数作为参数并返回一个新函数的可调用对象。
首先,我们来看一个简单的装饰器例子:
def simple_decorator(function):
def wrapper():
print("Something is happening before the function is called.")
function()
print("Something is happening after the function is called.")
return wrapper
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
在这个例子中,@simple_decorator
就是装饰器语法,它等价于say_hello = simple_decorator(say_hello)
。当我们调用say_hello()
时,实际上是在调用wrapper()
函数。
现在,让我们深入了解装饰器的工作原理。每当我们定义了一个装饰器并将其应用于一个函数时,这个装饰器就会在运行时被调用,并将被装饰的函数作为参数传递进去。然后,装饰器返回一个新的函数,这个新函数通常会包含一些额外的功能。
接下来,我们来看一个更实用的装饰器——日志记录装饰器:
import functools
def log_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with arguments {args} and keyword arguments {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@log_decorator
def add(a, b):
return a + b
add(1, 2)
这里,我们使用了functools.wraps
来保持原函数的名称和文档字符串。装饰器log_decorator
会在调用被装饰的函数前后打印一些信息,这在调试或记录日志时非常有用。
此外,装饰器还可以接受参数。带参数的装饰器本质上是一个返回装饰器的函数。这里有一个带参数的装饰器示例:
def repeat_decorator(times):
def actual_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return actual_decorator
@repeat_decorator(3)
def greet():
print("Hello, world!")
greet()
在这个例子中,repeat_decorator
接受一个参数times
,然后返回一个装饰器actual_decorator
。这个装饰器会重复调用被装饰的函数指定的次数。
总结一下,装饰器是一种强大的工具,它可以帮助我们在不修改原始代码的情况下增加新的功能。通过本文的介绍,你应该已经掌握了装饰器的基本用法,以及如何创建和应用自己的装饰器。现在,你可以开始在你的代码中使用装饰器来简化和增强你的程序了。