装饰器在Python社区中被广泛讨论,但很多初学者可能会觉得它们高不可攀。不过别担心,今天我们就来揭开装饰器的神秘面纱,用简单的方式理解并应用它们。
首先,我们来定义一个装饰器。装饰器本质上是一个接受函数作为参数并返回新函数的函数。听起来有点绕?没关系,让我们通过一个简单的例子来看看它是如何工作的。
def simple_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
@simple_decorator
def say_hello():
print("Hello!")
say_hello()
当你运行上述代码时,你会看到以下输出:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
看到了吗?simple_decorator
就是我们定义的装饰器,它“装饰”了 say_hello
函数,在调用 say_hello
时自动添加了一些额外的行为。
现在,让我们进一步,创建一个带参数的装饰器。这需要我们使用一层额外的函数来处理参数。
def decorator_with_args(num_times):
def actual_decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return actual_decorator
@decorator_with_args(3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
这段代码会输出:
Hello, Alice!
Hello, Alice!
Hello, Alice!
我们的 decorator_with_args
装饰器接受一个参数 num_times
,然后返回一个真正的装饰器 actual_decorator
,后者会重复执行被装饰的函数多次。
最后,我们来看一个更实际的例子,一个可以测量函数执行时间的装饰器。
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} ran in: {end_time - start_time} secs")
return result
return wrapper
@timing_decorator
def some_function():
time.sleep(2)
some_function()
这个装饰器会在每次调用被装饰的函数时计算并打印出它的运行时间。
通过这些例子,你可以看到装饰器不仅能够简化代码,还能增加代码的可读性和重用性。随着你对Python的深入学习,你会发现装饰器在库和框架中有着广泛的应用,理解它们的工作原理将大大提升你的编程技能。