MST

星途 面试题库

面试题:Python元类与属性访问控制的深度结合

如何通过元类来实现更灵活、更强大的属性访问控制机制?请设计一个元类,使得基于该元类创建的类,其所有属性在访问时都自动记录访问日志,同时要保证这种机制对类的使用者尽可能透明,并且要考虑如何处理属性的赋值、删除等操作时的日志记录。
28.8万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import logging

# 配置日志记录
logging.basicConfig(filename='attribute_access.log', level=logging.INFO,
                    format='%(asctime)s - %(message)s')


class LoggingMeta(type):
    def __new__(mcs, name, bases, attrs):
        def make_logging_wrapper(name, method):
            def wrapper(self, *args, **kwargs):
                if method.__name__ == '__getattribute__':
                    logging.info(f'Accessed attribute {name}')
                elif method.__name__ == '__setattr__':
                    logging.info(f'Set attribute {name} to {args[0]}')
                elif method.__name__ == '__delattr__':
                    logging.info(f'Deleted attribute {name}')
                return method(self, *args, **kwargs)
            return wrapper

        for attr_name, attr_value in attrs.items():
            if callable(attr_value) and attr_name in ('__getattribute__', '__setattr__', '__delattr__'):
                attrs[attr_name] = make_logging_wrapper(attr_name, attr_value)

        return super().__new__(mcs, name, bases, attrs)


class MyClass(metaclass=LoggingMeta):
    def __init__(self, value):
        self.value = value


if __name__ == "__main__":
    obj = MyClass(42)
    print(obj.value)
    obj.value = 100
    del obj.value
  1. 日志配置
    • 使用logging.basicConfig配置日志记录,将日志写入attribute_access.log文件,记录访问时间和操作信息。
  2. 元类LoggingMeta
    • __new__方法是元类创建类对象的方法。
    • make_logging_wrapper函数用于创建包装函数,在属性访问、赋值、删除时记录日志。
    • 遍历类的属性,如果属性是__getattribute____setattr____delattr__这些特殊方法,就用包装函数替换它们,以实现日志记录功能。
  3. 基于元类的类MyClass
    • 定义一个简单的类MyClass,使用LoggingMeta作为元类。
  4. 测试代码
    • 创建MyClass的实例obj,访问、赋值、删除属性,此时会自动记录相应的日志。