MST

星途 面试题库

面试题:Python类装饰器中等难度面试题

请编写一个Python类装饰器,它能够在类的每个方法执行前后打印日志,显示方法名以及执行时间。要求给出完整代码,并解释装饰器如何应用到类上。
41.3万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import time


def log_decorator(cls):
    class WrapperClass:
        def __init__(self, *args, **kwargs):
            self.wrapped = cls(*args, **kwargs)

        def __getattr__(self, name):
            def wrapper(*args, **kwargs):
                start_time = time.time()
                print(f"开始执行方法 {name},时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}")
                result = getattr(self.wrapped, name)(*args, **kwargs)
                end_time = time.time()
                print(f"方法 {name} 执行结束,时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())},执行耗时: {end_time - start_time} 秒")
                return result

            return wrapper

    return WrapperClass


@log_decorator
class MyClass:
    def method1(self):
        time.sleep(1)
        print("method1 执行中")


my_obj = MyClass()
my_obj.method1()

装饰器应用解释

  1. 定义装饰器函数 log_decorator
    • 这个装饰器函数接受一个类 cls 作为参数。
    • 在装饰器函数内部,定义了一个新的类 WrapperClass
    • WrapperClass__init__ 方法中,初始化了一个被包装的类的实例 self.wrapped
    • WrapperClass__getattr__ 方法用于拦截对被包装类属性的访问。当访问被包装类的方法时,会创建一个 wrapper 函数。
    • wrapper 函数在方法执行前打印开始日志,记录开始时间,执行被包装的方法,在方法执行后打印结束日志,记录结束时间和执行耗时。
  2. 应用装饰器到类 MyClass
    • 使用 @log_decorator 语法将 log_decorator 应用到 MyClass 类上。这相当于执行 MyClass = log_decorator(MyClass)
    • 当创建 MyClass 的实例 my_obj 并调用其方法 method1 时,实际上调用的是 WrapperClass__getattr__ 方法返回的 wrapper 函数,从而实现了在方法执行前后打印日志的功能。