MST

星途 面试题库

面试题:Python元类与描述符对列表元素修改行为的深度定制

假设你需要通过元类和描述符来深度定制列表元素的修改行为,例如每次修改元素时记录修改时间和修改者信息,同时在满足特定条件时阻止修改操作。请详细说明实现思路,并给出关键代码片段。
31.9万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 元类
    • 元类用于创建类,我们可以在元类中修改类的属性,比如为类添加自定义的方法或属性描述符。在这里,我们可以通过元类来为列表类添加描述符相关的设置。
    • 元类可以检查和修改类定义中的属性和方法,确保描述符正确地应用到列表元素的操作上。
  2. 描述符
    • 描述符是实现了 __get____set____delete__ 方法的类。对于列表元素的修改,我们主要关注 __set__ 方法。
    • __set__ 方法中,我们可以记录修改时间和修改者信息。同时,在该方法内添加特定条件的判断,若不满足条件则阻止修改操作。

关键代码片段

import datetime


# 定义描述符类
class ListElementDescriptor:
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        # 记录修改时间
        modification_time = datetime.datetime.now()
        # 假设修改者信息通过外部获取,这里简单设为 'default_user'
        modifier = 'default_user'
        # 特定条件判断,假设条件为 value 必须是整数
        if not isinstance(value, int):
            raise ValueError('修改的值必须是整数')
        instance.__dict__[self.name] = value
        print(f'元素 {self.name} 被 {modifier} 在 {modification_time} 修改为 {value}')


# 定义元类
class ListMeta(type):
    def __new__(mcls, name, bases, attrs):
        for key, value in attrs.items():
            if isinstance(value, ListElementDescriptor):
                setattr(mcls, key, value)
        return super().__new__(mcls, name, bases, attrs)


# 使用元类创建列表类
class CustomList(metaclass=ListMeta):
    def __init__(self, *args):
        self.data = list(args)

    def __getitem__(self, index):
        return self.data[index]

    def __setitem__(self, index, value):
        self.__dict__['data'][index] = value


# 使用示例
custom_list = CustomList(1, 2, 3)
custom_list[1] = 4