Python装饰器函数详解,提高代码重用性
Python中的装饰器是一种特殊的函数,用于修改其他函数的功能。装饰器可以在不修改函数代码的情况下,改变函数的行为。通过装饰器,可以使函数的行为更加灵活,提高代码的重用性、可读性和可维护性。
一、装饰器的基本语法
在Python中,装饰器以 "@" 符号开始,后面跟着一个函数名。例如:
@decorator
def func(arg1, arg2):
pass
其中,decorator是定义的装饰器函数,func是被装饰的函数。装饰器函数必须接受一个函数作为参数,并返回一个新的函数。新的函数通常会包装原来的函数,以实现要求。
二、装饰器的例子1:添加日志
假设需要添加日志到一个函数中,记录函数的调用时间和参数信息。可以使用下面的装饰器函数实现:
import logging
import time
def log(func):
def wrapper(*args, **kwargs):
logging.basicConfig(filename='example.log', level=logging.INFO)
logging.info('Function "%s" called with args: %s, %s', func.__name__, args, kwargs)
return func(*args, **kwargs)
return wrapper
@log
def add(x, y):
return x + y
result = add(1, 2)
在上面的例子中,log是定义的装饰器函数。它接受一个函数作为参数,返回一个新的函数wrapper。wrapper函数负责添加日志信息,并调用原函数add。
在add函数上加上@log装饰器之后,add函数的行为发生了变化。现在每次调用add函数时,都会自动添加日志,输出日志信息。
三、装饰器的例子2:添加缓存
假设需要实现一个缓存功能,将函数的调用结果缓存起来,避免重复计算。可以使用下面的装饰器函数:
import functools
def cache(func):
cache = {}
@functools.wraps(func)
def wrapper(*args):
if args in cache:
print(f"cache hit: {args}")
return cache[args]
else:
print(f"cache miss: {args}")
value = func(*args)
cache[args] = value
return value
return wrapper
@cache
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
result = fib(10)
在上面的例子中,cache是定义的装饰器函数。它接受一个函数作为参数,返回一个新的函数wrapper。wrapper函数负责实现缓存功能,每次调用函数之前先检查结果是否已经被缓存,如果是则直接返回结果,否则计算结果并缓存起来。
在fib函数上加上@cache装饰器之后,每次调用fib函数时,都会自动检查缓存,避免重复计算。
四、装饰器的例子3:限制函数调用频率
假设需要限制某个函数的调用频率,例如每分钟只能调用一次。可以使用下面的装饰器函数:
import time
import functools
def limit_rate(rate):
def wrapper(func):
last_call = time.time()
@functools.wraps(func)
def inner(*args, **kwargs):
nonlocal last_call
now = time.time()
interval = 60 / rate
if now - last_call < interval:
print(f"Rate limited: {func.__name__}")
return
else:
last_call = now
return func(*args, **kwargs)
return inner
return wrapper
@limit_rate(2)
def some_function():
print("Hello, world!")
在上面的例子中,limit_rate是定义的装饰器函数。它接受一个参数rate,表示调用频率,返回一个新的函数wrapper。wrapper函数负责实现限制调用频率的功能,每次调用函数之前判断距离上次调用的时间是否超过规定的时间间隔,如果超过则允许调用,否则返回None。
在some_function函数上加上@limit_rate(2)装饰器之后,每分钟只能调用两次,超过限制的调用会被忽略。
五、总结
装饰器是Python中非常有用的特性,可以用于增强函数的功能,提高代码的重用性、可读性和可维护性。要编写好装饰器,需要掌握一些基本概念和语法,例如闭包、装饰器函数的参数和返回值等。在实际应用中,可以根据需要编写定制化的装饰器,以实现自己的业务需求。
