在Python中,我们可以使用方法或者类来实现装饰器。选择使用方法还是类作为装饰器,主要取决于具体的应用场景。
使用方法作为装饰器
当装饰器的功能相对简单,不需要保持任何状态信息时,使用方法作为装饰器是一个不错的选择。这种情况下,装饰器通常只是对被装饰函数进行一些额外的操作,比如记录日志、增加权限检查等。
下面是一个简单的例子,使用方法作为装饰器实现日志记录功能:
def log_execution(func):def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")result = func(*args, **kwargs)print(f"Function {func.__name__} returned: {result}")return resultreturn wrapper@log_execution
def add_numbers(a, b):return a + bresult = add_numbers(2, 3)
# Output:
# Calling function: add_numbers
# Function add_numbers returned: 5
在这个例子中,log_execution
是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数。新函数在执行被装饰的函数前后,分别打印函数名和返回值。
使用类作为装饰器
当装饰器需要保持一些状态信息,或者需要更复杂的功能时,使用类作为装饰器会更加合适。这种情况下,装饰器可以利用类的属性和方法来实现更复杂的逻辑。
下面是一个使用类作为装饰器的例子,实现一个缓存功能:
class cache:def __init__(self, func):self.func = funcself.cache = {}def __call__(self, *args, **kwargs):key = tuple(args) + tuple(kwargs.items())if key in self.cache:print(f"Returning cached result for {self.func.__name__}")return self.cache[key]else:result = self.func(*args, **kwargs)self.cache[key] = resultreturn result@cache
def fibonacci(n):if n <= 1:return nelse:return fibonacci(n-1) + fibonacci(n-2)print(fibonacci(10))
print(fibonacci(10))
# Output:
# Calculating fibonacci(10)
# 55
# Returning cached result for fibonacci
# 55
在这个例子中,cache
是一个类,它充当装饰器的角色。cache
类保存了被装饰函数的引用,以及一个缓存字典。当被装饰的函数fibonacci
被调用时,cache
类会先检查缓存中是否已经存在计算结果,如果存在则直接返回,否则计算结果并存入缓存。
总的来说,使用方法作为装饰器更适合于简单的装饰器功能,而使用类作为装饰器则更适合于需要保持状态信息或实现更复杂逻辑的场景。