欢迎访问宙启技术站
智能推送

Python函数的装饰器(Decorator)的使用示例

发布时间:2023-07-06 14:49:31

装饰器是Python函数的一种功能,用于在不修改原始函数代码的情况下向其添加额外的功能。装饰器通过将函数作为参数传递给另一个函数,并返回一个包装函数来实现这一功能。在本文中,我将为您提供一些使用装饰器的示例。

首先,让我们来看一个简单的示例,使用装饰器来计算函数的执行时间:

import time

def calculate_time(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"Function {func.__name__} took {end - start} seconds to execute.")
        return result
    return wrapper

@calculate_time
def my_function():
    # do something
    pass

my_function()

在上面的示例中,我们定义了一个名为calculate_time的装饰器,这个装饰器用于计算被装饰函数的执行时间。装饰器本身是一个函数,它接受要装饰的函数作为参数,并返回一个新的包装函数wrapper。在包装函数中,我们使用time模块来记录函数的开始和结束时间,然后计算执行时间并打印出来。

使用装饰器时,我们只需要在要装饰的函数之前添加@calculate_time,这样就可以自动计算函数的执行时间了。

另一个常见的用例是为函数添加日志记录功能。下面的示例演示了如何使用装饰器来实现这个功能:

import logging

def log_func(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Function {func.__name__} was called with arguments {args} and {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@log_func
def calculate_sum(a, b):
    return a + b

calculate_sum(2, 3)

在上面的示例中,我们定义了一个名为log_func的装饰器,用于为函数添加日志记录功能。在包装函数中,我们使用logging模块来记录函数的名称和传递给函数的参数。然后,我们调用原始函数并返回其结果。

使用装饰器时,我们只需要在要装饰的函数之前添加@log_func,这样函数调用的详细信息就会被记录下来了。

除了对函数进行装饰外,我们还可以对类进行装饰。下面的示例演示了如何使用装饰器来添加一个计数器属性到一个类中的所有方法:

def add_counter(cls):
    class Wrapper:
        def __init__(self, *args, **kwargs):
            self.counter = 0
            self.wrapped = cls(*args, **kwargs)
        
        def __getattr__(self, name):
            attr = getattr(self.wrapped, name)
            if callable(attr):
                return self.wrap_method(attr)
            return attr
        
        def wrap_method(self, method):
            def wrapped_method(*args, **kwargs):
                self.counter += 1
                return method(*args, **kwargs)
            return wrapped_method
    
    return Wrapper

@add_counter
class MyClass:
    def method1(self):
        pass
    
    def method2(self):
        pass

obj = MyClass()
obj.method1()
obj.method2()
print(obj.counter)

在上面的示例中,我们定义了一个名为add_counter的装饰器,用于向类的所有方法添加一个计数器属性。在装饰器中,我们定义了一个名为Wrapper的包装类,它接受类的实例化参数并创建一个原始类的实例。然后,我们通过定义__getattr__方法,将调用类的方法转发给原始类,并在调用方法时增加计数器。

使用装饰器时,我们只需要在要装饰的类之前添加@add_counter,这样类的所有方法都会自动具有计数器功能。

这些示例只是装饰器的一小部分用例,实际上装饰器可以用于许多其他场景,例如缓存函数结果、验证用户权限等等。希望本文能够帮助您理解和应用装饰器的概念和用法。