Python装饰器函数:添加额外的功能或修饰函数
Python装饰器函数
Python装饰器函数是一种很有用的编程技巧,它可以用来添加额外的功能或修饰函数。在Python中,函数是一种对象,因此可以将函数作为参数传递给其他函数,也可以将其作为返回值返回。
装饰器函数就是用来修饰其他函数的函数,它接受一个函数作为参数,并返回一个修饰后的函数。用装饰器函数修改其他函数,可以让我们在不改变原始函数的情况下添加功能,这样可以使得代码更加简洁和易于维护。
下面我们来看一个简单的装饰器函数。
def my_decorator(func):
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello world!")
我们定义了一个名为my_decorator的函数,它接受一个func参数,这个参数是一个函数对象。my_decorator返回一个wrapper函数,它在调用原始函数之前和之后打印一些信息。
我们然后用@my_decorator装饰了一个名为say_hello的函数,现在每次调用say_hello函数,实际上会调用wrapper函数。因此,在调用原始函数之前和之后,会输出一些信息。
下面我们来看一下如何编写一个可以带参数的函数装饰器。
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Before the function is called.")
result = func(*args, **kwargs)
print("After the function is called.")
return result
return wrapper
在这个例子中,wrapper函数可以处理任意数量和类型的参数。我们使用*args和**kwargs来表示任意数量和任意类型的参数。这就允许我们使用装饰器来修饰任意类型的函数。
现在我们来看一下装饰器函数可以实现的一些常见的额外功能。
1. 记录日志
一个通用的应用场景是记录函数调用的日志。你可以在函数调用的前后记录函数名、参数和返回值。
def log_func_calls(func):
def wrapper(*args, **kwargs):
print(f"Call {func.__name__} with {args}")
result = func(*args, **kwargs)
print(f"Return {result}")
return result
return wrapper
在这个装饰器中,我们获取函数名和参数,记录在日志中,然后调用原函数,并将返回值记录在日志中。如果调用的函数返回的不是None,那么返回结果。
2. 记录时间
你也可以用装饰器来记录函数运行的时间。
import time
def time_it(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Call {func.__name__}: {end - start:.5f} seconds")
return result
return wrapper
这个装饰器实现了一个计时器,它记录了调用函数所花费的时间,并打印出来。time.time()函数返回当前时间,使用start来记录调用函数之前的时间,使用end来记录调用函数之后的时间。我们还要使用Python中的格式化字符串来将运行时间输出为保留5位小数的字符串。
3. 缓存函数
有时候,我们希望避免重复计算某个函数。这时候,可以使用装饰器来实现一个缓存的版本,避免重复计算。
def memo(func):
cache = {}
def wrapper(*args):
if args in cache:
return cache[args]
result = func(*args)
cache[args] = result
return result
return wrapper
这个装饰器实现了一个简单的缓存。如果我们已经计算过一个函数,那么我们就可以在缓存中找到结果,而不是再次计算。注意,我们使用args作为缓存的键,这意味着单个参数的函数才能使用这个缓存。
在 Python 中使用装饰器可以给我们带来很多好处。它让我们可以在不修改原函数的前提下,实现某些额外的功能。因此,装饰器可以让我们的代码更加清晰、简洁和易于维护。
