MST

星途 面试题库

面试题:Python装饰器在类方法中的应用

假设有一个类,类中有多个方法。编写一个装饰器,能够应用于类中的所有实例方法,实现对每个方法调用时记录日志(记录方法名和传入参数)。请给出详细的代码实现和说明。
31.0万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import functools


def log_decorator(func):
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        print(f"调用方法: {func.__name__}, 传入参数: args={args}, kwargs={kwargs}")
        return func(self, *args, **kwargs)
    return wrapper


def decorate_all_methods(cls):
    for name, method in cls.__dict__.items():
        if callable(method) and not name.startswith('__'):
            setattr(cls, name, log_decorator(method))
    return cls


@decorate_all_methods
class MyClass:
    def method1(self, a, b):
        return a + b

    def method2(self, c):
        return c * 2


说明

  1. log_decorator 装饰器

    • 这个装饰器接受一个函数 func 作为参数。
    • 使用 functools.wraps 来保留被装饰函数的元信息(如函数名、文档字符串等)。
    • 定义内部函数 wrapper,它接受 self(因为是实例方法)以及可变位置参数 *args 和可变关键字参数 **kwargs
    • wrapper 函数内部,首先打印方法名和传入的参数,然后调用原始函数 func 并返回其结果。
  2. decorate_all_methods 装饰器

    • 这个装饰器接受一个类 cls 作为参数。
    • 使用 cls.__dict__ 遍历类中的所有属性。
    • 对于每个可调用且不是以双下划线开头的属性(即实例方法),使用 log_decorator 对其进行装饰,并通过 setattr 将装饰后的方法重新设置回类中。
    • 最后返回装饰后的类。
  3. MyClass

    • 定义了两个实例方法 method1method2
    • 使用 @decorate_all_methods 装饰器对 MyClass 类进行装饰,这样类中的所有实例方法都会被 log_decorator 装饰,从而在调用时记录日志。

例如,使用以下代码测试:

obj = MyClass()
result1 = obj.method1(1, 2)
result2 = obj.method2(3)

运行上述代码,会在控制台输出:

调用方法: method1, 传入参数: args=(1, 2), kwargs={}
调用方法: method2, 传入参数: args=(3,), kwargs={}