在Python编程中,装饰器是一种高级Python语法。它本质上是一个接受函数作为参数并返回新函数的函数。装饰器为程序员提供了一种修改其他函数或类的行为的强大方式,同时保持了代码的简洁性和模块化。
1. 装饰器基础
首先,我们来定义一个简单的装饰器。装饰器用@
符号表示,放在被装饰函数的上方。下面是一个简单的例子:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
当运行say_hello()
时,输出将会是:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
在这个例子中,my_decorator
就是一个装饰器。它接收一个函数作为参数(在这里是say_hello
),并返回一个新的函数wrapper
。当我们调用say_hello()
时,实际上是在调用wrapper()
函数。
2. 带参数的装饰器
接下来,我们将创建一个可以接受参数的装饰器。为了实现这一点,我们需要在装饰器外层再包裹一层函数。例如:
def decorator_with_args(arg):
def real_decorator(func):
def wrapper(x, y):
print(f"Decorator arg: {arg}")
print(f"Wrapper args: {x}, {y}")
func(x, y)
return wrapper
return real_decorator
@decorator_with_args("I am a decorator argument")
def add(x, y):
print(f"Add function: {x + y}")
add(1, 2)
输出结果会显示装饰器和被装饰函数的参数:
Decorator arg: I am a decorator argument
Wrapper args: 1, 2
Add function: 3
3. 实用的装饰器:日志记录
现在,让我们构建一个更实用的装饰器——日志记录。这个装饰器会在每次函数调用时记录日志信息。
import datetime
import functools
def log_decorator(log_file):
def real_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
current_time = datetime.datetime.now()
with open(log_file, "a") as file:
file.write(f"Calling function {
func.__name__} at {
current_time}
")
result = func(*args, **kwargs)
with open(log_file, "a") as file:
file.write(f"Function {
func.__name__} returned {
result}
")
return result
return wrapper
return real_decorator
@log_decorator("log.txt")
def add(x, y):
return x + y
add(5, 3)
上述代码中的log_decorator
装饰器会在调用任何被它装饰的函数时,在指定的日志文件中记录下函数的调用时间和返回值。这样,我们就可以轻松地跟踪函数的执行情况,而无需在函数内部添加任何日志代码。
通过以上步骤,我们不仅了解了Python装饰器的基本概念,还学习了如何创建和应用不同类型的装饰器。现在,你已经具备了使用装饰器来增强你的Python代码的能力。记住,装饰器是一个非常强大的工具,但也需要谨慎使用,以保证代码的可读性和可维护性。