Python 函数装饰器

goallin / 2023-08-17 / 原文

Python 函数装饰器

Python function decorator 函数装饰器的典型行为:把被装饰的函数替换成新函数,二者接受相同的参数,而且(通常)返回被装饰的函数本该返回的值,同时还会做些额外操作。它不修改原来的函数,还给函数增加新的功能,而是使得调用原函数的时候附加一些功能。

记录函数执行时间

import random
import time


# 记录函数执行时间
def logging_time(func):
    def logger(*args, **kwargs):
        print(f"{func.__name__} starts")
        start_t = time.time()
        value_returned = func(*args, **kwargs)
        end_t = time.time()
        print(f"{func.__name__} ends; used time: {end_t - start_t:.2f} s")
        return value_returned
    return logger


@logging_time
def func2():
    delay = random.randint(3, 5) * 0.1
    time.sleep(delay)


def test_func2():
    func2()

缓存函数执行结果

对于一些耗时计算,可以使用函数装饰器来缓存执行结果

import time


def logging_time(func):
    def logger(*args, **kwargs):
        print(f"{func.__name__} starts")
        start_t = time.time()
        value_returned = func(*args, **kwargs)
        end_t = time.time()
        print(f"{func.__name__} ends; used time: {end_t - start_t:.2f} s")
        return value_returned
    return logger


def memoize(func):
    cache = {}

    def wrapper(*args):
        if args in cache:
            return cache[args]
        result = func(*args)
        cache[args] = result
        return result
    return wrapper


def fibonacci(n):
    return n if n <= 1 else fibonacci(n-1) + fibonacci(n-2)


@memoize
def fibonacci_with_cache(n):
    return n if n <= 1 else fibonacci_with_cache(n-1) + fibonacci_with_cache(n-2)


@logging_time
def func1():
    print(f"fibonacci(36) = {fibonacci(36)}")


@logging_time
def func2():
    print(f"fibonacci_with_cache(300) = {fibonacci_with_cache(300)}")


def test_fibonacci():
    func1()
    func2()
# 输出
func1 starts
fibonacci(36) = 14930352
func1 ends; used time: 3.64 s
func2 starts
fibonacci_with_cache(300) = 222232244629420445529739893461909967206666939096499764990979600
func2 ends; used time: 0.00 s