使用Python装饰器在函数中添加新功能
Python 装饰器是一个非常有用的 Python 语言特性,它允许我们在不改变已有代码的情况下为它们添加新的功能。这种方式可以被看作是非常重要的编程技巧之一。在本文中,我们将学习如何使用 Python 装饰器在函数中添加新功能。
装饰器是函数或类,其主要目的是扩展其他函数或类的功能。装饰器在 Python 中是以 @ 符号为开头的语法糖,可以轻松地将它们应用于已有的函数或类。下面是一个简单的装饰器函数示例:
def my_decorator(func):
def wrapper():
print("Before function is called.")
func()
print("After function is called.")
return wrapper
在上面的代码中,我们定义了一个装饰器函数 my_decorator,它会在被装饰函数执行前后打印一些日志。装饰器接收一个函数作为参数,并通过 wrapper 函数来包装它,从而引入新的行为。我们可以通过以下方式使用装饰器:
@my_decorator
def say_hello():
print("Hello!")
在上面的代码中,我们使用 @my_decorator 将 say_hello 函数与装饰器绑定在一起。这表示当我们调用 say_hello 函数时,它实际上会被装饰器包装并执行。
运行代码,结果为:
Before function is called. Hello! After function is called.
可以看到,当我们调用 say_hello() 函数时,会按照我们所期望的顺序打印日志。
装饰器的应用非常广泛,有许多场景可以利用装饰器来实现特定的功能。下面是一些常见的例子。
1. 记录函数运行时间的装饰器
import time
def time_it(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time} seconds to run.")
return result
return wrapper
在上面的代码中,我们定义了一个装饰器函数 time_it,它可以测量被装饰函数的运行时间并打印出来。我们可以在需要测量时间的函数前使用 @time_it 装饰器来使用该功能。
@time_it
def some_process():
# do some expensive task here
time.sleep(2)
在上面的代码中,使用 time.sleep(2) 模拟一个耗时的操作。如果我们现在调用 some_process() 函数,会按照下面的方式打印日志信息:
Function some_process took 2.0009610652923584 seconds to run.
可以看到,在函数执行结束后,装饰器成功记录了它的运行时间并输出了日志信息。
2. 记录函数调用次数的装饰器
def count_calls(func):
def wrapper(*args, **kwargs):
wrapper.num_calls += 1
print(f"Function {func.__name__} has been called {wrapper.num_calls} times.")
return func(*args, **kwargs)
wrapper.num_calls = 0
return wrapper
在上面的代码中,我们定义了一个装饰器函数 count_calls,它可以记录被装饰函数的调用次数并打印出来。我们可以在需要统计调用次数的函数前使用 @count_calls 装饰器来使用该功能。
@count_calls
def some_function():
print("Hello")
如果我们现在调用 some_function() 函数,它会经过装饰器包装执行。装饰器会记录每次函数的调用次数,并按照下面的方式打印输出信息:
Function some_function has been called 1 times. Hello Function some_function has been called 2 times. Hello
可以看到,装饰器成功记录了函数的调用次数并打印出来。
Python 装饰器为我们提供了一种不侵入代码更改的方式来扩展已有功能。使用装饰器,我们可以通过添加新的代码来改进现有的功能,而不必更改函数或类的代码。这使得我们可以轻松地添加与已有代码不同的功能,而无需重写代码。希望这篇文章能够帮助你理解 Python 装饰器的概念和应用场景。
