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

Python装饰器:装饰器函数实现和应用

发布时间:2023-05-29 03:13:51

Python装饰器是一种高级编程技术,它可以在不修改原有代码的情况下添加新的功能。装饰器本质上是一个函数,它接收另一个函数作为参数,然后返回一个新的函数。这个新函数包装了原有的函数,并添加了一些额外的功能。

装饰器函数实现

装饰器函数通常使用装饰器语法来定义。它可以接收一个函数作为参数,并返回一个新的函数。下面是一个简单的装饰器函数的示例代码:

def decorator(func):
    def wrapper():
        print("Before function is called.")
        func()
        print("After function is called.")
    return wrapper

在这个示例中,decorator函数是一个装饰器函数。它接收一个函数作为参数,并返回一个新的函数wrapper。这个wrapper函数包装了原有的函数,并添加了一些额外的功能。

下面是一个简单的使用装饰器函数的示例代码:

@decorator
def say_hello():
    print("Hello World.")
    
say_hello()

在这个示例中,我们使用装饰器语法将decorator函数应用于say_hello函数。当我们调用say_hello函数时,它实际上调用wrapper函数。wrapper函数将打印“Before function is called.”,然后调用原有的say_hello函数,最后将打印“After function is called.”。

应用场景

Python装饰器在实际的开发中具有广泛的应用场景。下面是一些常见的应用场景:

1. 记录程序运行时间

我们可以使用装饰器函数来记录程序运行时间。下面是一个简单的装饰器函数的示例代码:

import time

def time_it(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print(f"Execution time: {end - start}s")
    return wrapper

在这个示例中,time_it函数是一个装饰器函数。它接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数包装了原有的函数,并添加了计时的功能。

下面是一个简单的使用装饰器函数来记录程序运行时间的示例代码:

@time_it
def my_function():
    time.sleep(1)
    
my_function()

在这个示例中,我们使用装饰器语法将time_it函数应用于my_function函数。当我们调用my_function函数时,它实际上调用wrapper函数。wrapper函数将记录程序运行时间,并将其打印出来。

2. 对函数进行缓存

我们可以使用装饰器函数来对函数进行缓存。下面是一个简单的装饰器函数的示例代码:

def cache(func):
    cache = {}
    def wrapper(*args, **kwargs):
        key = str(args) + str(kwargs)
        if key not in cache:
            cache[key] = func(*args, **kwargs)
        return cache[key]
    return wrapper

在这个示例中,cache函数是一个装饰器函数。它接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数包装了原有的函数,并添加了缓存的功能。

下面是一个简单的使用装饰器函数来对函数进行缓存的示例代码:

@cache
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)
    
print(fibonacci(10))

在这个示例中,我们使用装饰器语法将cache函数应用于fibonacci函数。当我们调用fibonacci函数时,它实际上调用wrapper函数。wrapper函数将检查缓存中是否有相应的结果。如果有,它将直接返回缓存中的结果。否则,它将调用原有的fibonacci函数,并将其结果存储在缓存中。

3. 检查函数参数类型

我们可以使用装饰器函数来检查函数的参数类型。下面是一个简单的装饰器函数的示例代码:

def check_types(*types):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i, arg in enumerate(args):
                if not isinstance(arg, types[i]):
                    raise TypeError(f"Expected {types[i]}, but got {type(arg)}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

在这个示例中,check_types函数是一个装饰器函数。它接收一个或多个类型作为参数,并返回一个新的装饰器函数decorator。decorator函数接收一个函数作为参数,并返回一个新的函数wrapper。wrapper函数包装了原有的函数,并添加了类型检查的功能。

下面是一个简单的使用装饰器函数来检查函数参数类型的示例代码:

@check_types(int, str)
def my_function(number, text):
    print(f"{number} {text}")
    
my_function(10, "Hello World")

在这个示例中,我们使用装饰器语法将check_types函数应用于my_function函数。当我们调用my_function函数时,它实际上调用wrapper函数。wrapper函数将检查参数的类型是否符合要求。如果不符合要求,它将抛出一个TypeError异常。否则,它将调用原有的my_function函数。

结语

Python装饰器是一个非常强大的工具,它可以帮助我们实现更加优雅和灵活的代码。在实际的开发中,我们应该合理地运用装饰器函数,以便提高代码的可读性和可维护性。