Python函数装饰器:用法和示例
Python函数装饰器是一种特殊的函数,它接受另一个函数作为参数,并返回一个新的函数作为结果。函数装饰器通常用于修改现有函数的行为或增强其功能,而不修改它的源代码。使用函数装饰器可以让代码更加灵活和可维护,因为它可以将代码的不同部分分离开来,使得修改更加容易。
函数装饰器的用法:
1.定义装饰器函数
首先,需要定义一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数。在新的函数中,可以添加一些处理逻辑来改变原函数的行为或增强其功能。下面是一个简单的装饰器函数的例子:
def my_decorator(func):
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")
return wrapper
2.使用装饰器装饰函数
接下来,使用装饰器将原函数装饰起来。这可以通过在原函数定义之前加上装饰器函数的名称,并在装饰器函数后面写上原函数的名称,来实现。例如:
@my_decorator
def say_hello():
print("Hello, world!")
3.调用装饰后的函数
现在,可以调用装饰后的函数了。在调用装饰后的函数时,实际上是调用了新的函数,而不是原函数。例如:
say_hello()
上面的代码输出如下结果:
Before the function is called.
Hello, world!
After the function is called.
装饰器可以用于各种不同的场景,包括日志记录、性能分析、输入验证、缓存等。下面介绍一些常见的装饰器示例。
1. 日志记录装饰器
日志记录装饰器可以记录函数的调用信息,包括函数名、参数、返回值等。下面是一个简单的日志记录装饰器的示例:
import logging
def log(func):
def wrapper(*args, **kwargs):
logging.info(f"Calling function: {func.__name__}")
logging.info(f"Args: {args}")
logging.info(f"Kwargs: {kwargs}")
result = func(*args, **kwargs)
logging.info(f"Return value: {result}")
return result
return wrapper
@log
def add(x, y):
return x + y
add(2, 3)
上面的代码会将函数 add 的调用信息记录到日志中。
2. 性能分析装饰器
性能分析装饰器可以测量函数的执行时间,以便优化程序的性能。下面是一个简单的性能分析装饰器的示例:
import time
def timing(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} took {end_time - start_time:.2f} seconds to execute.")
return result
return wrapper
@timing
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
fibonacci(30)
上面的代码会测量函数 fibonacci 的执行时间,并输出到控制台。
3. 输入验证装饰器
输入验证装饰器可以验证函数的参数是否符合要求,以避免出现不必要的错误。下面是一个简单的输入验证装饰器的示例:
def validate(func):
def wrapper(*args, **kwargs):
if len(args) < 2 or not isinstance(args[0], int) or not isinstance(args[1], int):
raise ValueError("Invalid input.")
result = func(*args, **kwargs)
return result
return wrapper
@validate
def divide(x, y):
return x / y
divide("a", "b")
上面的代码会验证函数 divide 的参数是否为整数,并抛出 ValueError 异常。
4. 缓存装饰器
缓存装饰器可以缓存函数的输出结果,以避免重复计算。下面是一个简单的缓存装饰器的示例:
def cache(func):
cache_dict = {}
def wrapper(*args, **kwargs):
key = str(args) + str(kwargs)
if key in cache_dict:
return cache_dict[key]
else:
result = func(*args, **kwargs)
cache_dict[key] = result
return result
return wrapper
@cache
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)
factorial(5)
上面的代码会将函数 factorial 的输出结果缓存起来,避免重复计算,提高程序的效率。
总结
Python函数装饰器是一种强大的编程技术,可以让代码更加灵活、可维护。使用装饰器可以将代码的不同部分分离开来,使得修改更加容易。常见的装饰器场景包括日志记录、性能分析、输入验证、缓存等。使用装饰器可以大大提高代码的效率和可读性,值得掌握。
