Python装饰器的基本原理和用法
Python装饰器是一种语法糖,可以用于在不修改原函数的情况下,为函数添加额外的功能。装饰器函数可以接受一个函数作为输入,并返回一个新的函数作为输出。
装饰器的基本原理是,定义一个装饰器函数,该函数接受一个函数作为参数,并返回一个新的函数。在这个新的函数中,可以在调用原函数前后添加额外的代码。
下面是一个简单的装饰器示例,用于在调用函数时打印函数名:
def print_function_name(func):
def wrapper(*args, **kwargs):
print("Calling function:", func.__name__)
return func(*args, **kwargs)
return wrapper
@print_function_name
def add(a, b):
return a + b
result = add(1, 2) # 调用函数 add,并打印函数名
print(result) # 输出:3
在上面的示例中,我们定义了一个装饰器函数 print_function_name,该函数接受一个函数作为参数,并返回一个新的函数 wrapper。在 wrapper 函数中,我们首先打印被装饰函数的名称,然后调用被装饰函数,并返回其结果。
通过在被装饰函数 add 的定义前面添加 @print_function_name,我们将 add 函数传递给装饰器函数,并将其结果重新赋值给 add。这样,当我们调用 add 函数时,实际上是调用了装饰器函数返回的 wrapper 函数。
除了打印函数名之外,装饰器还可以实现很多其他功能,例如计时、缓存、权限验证等。下面是一个使用装饰器实现计时功能的示例:
import time
def timing(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print("Function", func.__name__, "took", end_time - start_time, "seconds.")
return result
return wrapper
@timing
def calculate_sum(n):
return sum(range(n))
result = calculate_sum(10000000) # 调用函数并计时
print(result) # 输出:49999995000000
在上面的示例中,我们定义了一个装饰器函数 timing,该函数接受一个函数作为参数,并返回一个新的函数 wrapper。在 wrapper 函数中,我们首先记录当前时间作为函数开始时间,然后调用被装饰函数,并记录当前时间作为函数结束时间。最后,我们打印函数的名称和执行时间,并返回函数的结果。
通过在被装饰函数 calculate_sum 的定义前面添加 @timing,我们将 calculate_sum 函数传递给装饰器函数,并将其结果重新赋值给 calculate_sum。这样,当我们调用 calculate_sum 函数时,实际上是调用了装饰器函数返回的 wrapper 函数。
装饰器可以帮助我们在不修改原函数的情况下,为函数添加额外的功能,并且可以在多个函数之间共享装饰器。装饰器可以大大简化代码,提高代码的复用性和可维护性。
