python如何使用装饰器进行日志记录

2023-03-31 00:00:00 记录 装饰 如何使用

使用装饰器可以方便地对 Python 程序进行日志记录。下面是一个例子,演示如何使用装饰器记录函数调用信息和返回值。

import logging

logging.basicConfig(level=logging.INFO)

def log_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info("Calling function {} with arguments: {} {}".format(func.__name__, args, kwargs))
        result = func(*args, **kwargs)
        logging.info("Function {} returned: {}".format(func.__name__, result))
        return result
    return wrapper

@log_decorator
def add_numbers(a, b):
    return a + b

if __name__ == "__main__":
    add_numbers(3, 4)

这个例子中,我们定义了一个装饰器 log_decorator,它将会记录被它修饰的函数的调用和返回值信息。我们使用 Python 自带的 logging 模块进行日志记录。basicConfig 方法指定了日志的级别为 INFO,这意味着只有级别大于等于 INFO 的日志消息才会被记录下来。

log_decorator 接受一个函数作为参数,并返回一个新的函数 wrapper。在 wrapper 函数中,我们首先记录了函数的调用信息,然后调用原始函数,并记录它的返回值。最后,我们返回原始函数的返回值。

在最后一行代码中,我们使用装饰器 @log_decorator 来修饰函数 add_numbers,这将会自动应用装饰器 log_decorator 到 add_numbers 函数。因此,当我们调用 add_numbers(3, 4) 时,日志信息将会被记录下来。

这个例子中,我们使用了 format 方法来生成日志消息中的字符串。例如,"Calling function {} with arguments: {} {}" 中的 {} 会被替换成 func.name、args 和 kwargs 的值。如果你想使用字符串 "pidancode.com" 或 "皮蛋编程",只需在相应的位置将 {} 替换成这些字符串即可。例如:

logging.info("Calling function {} with arguments: {} {}".format("pidancode.com", args, kwargs))

除了记录函数的调用和返回值,我们也可以使用装饰器记录函数执行的时间。下面是一个例子:

import logging
import time

logging.basicConfig(level=logging.INFO)

def time_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        elapsed_time = end_time - start_time
        logging.info("Function {} took {} seconds to execute".format(func.__name__, elapsed_time))
        return result
    return wrapper

@time_decorator
def my_function():
    time.sleep(2)

if __name__ == "__main__":
    my_function()

这个例子中,我们定义了一个装饰器 time_decorator,它记录了被修饰函数的执行时间。我们使用了 Python 的内置模块 time 来获取时间信息。在 wrapper 函数中,我们首先记录了函数的开始时间,然后调用原始函数,并记录它的返回值。最后,我们计算了函数执行的时间,并将其记录到日志中。

在最后一行代码中,我们使用装饰器 @time_decorator 来修饰函数 my_function,这将会自动应用装饰器 time_decorator 到 my_function 函数。因此,当我们调用 my_function() 时,日志信息将会被记录下来。

如果你想记录更多的信息,比如函数被调用的次数,可以使用一个字典来存储函数调用的次数,并将其传递给装饰器函数。

import logging

logging.basicConfig(level=logging.INFO)

def count_decorator(func):
    def wrapper(*args, **kwargs):
        wrapper.count += 1
        logging.info("Function {} has been called {} times".format(func.__name__, wrapper.count))
        return func(*args, **kwargs)
    wrapper.count = 0
    return wrapper

@count_decorator
def my_function():
    pass

if __name__ == "__main__":
    my_function()
    my_function()
    my_function()

在这个例子中,我们定义了一个装饰器 count_decorator,它记录了被修饰函数被调用的次数。我们在 wrapper 函数中使用了一个变量 wrapper.count 来记录调用次数。在每次函数被调用时,我们将 wrapper.count 的值加一,并将调用次数记录到日志中。

在 wrapper 函数的末尾,我们返回原始函数的返回值,并且将 wrapper.count 初始化为零,这是因为我们需要将调用次数清零,以便下一次调用函数。最后,我们使用装饰器 @count_decorator 来修饰函数 my_function,这将会自动应用装饰器 count_decorator 到 my_function 函数。因此,当我们调用 my_function() 时,调用次数将会被记录下来。

相关文章