You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python自定义类如何实现下标访问返回可变视图,类numpy数组修改同步

你当前的实现输出False,核心原因是Python原生列表的切片操作会生成新的独立列表,你在__getitem__中返回的Custom(items[key])实际持有了切片得到的新列表,修改这个新列表自然不会同步到原实例的列表。

要实现类似numpy数组的视图效果,核心思路是:所有Custom实例共享同一份底层存储的列表,每个实例仅记录自己对应数据的偏移量和长度,所有读写操作都基于偏移量映射到原始列表的对应位置,不做数据拷贝。

完整实现代码

class ListView:
    """支持视图逻辑的列表代理,兼容.items[]读写操作"""
    def __init__(self, custom_inst):
        self.inst = custom_inst
    
    def __getitem__(self, key):
        if isinstance(key, int):
            if key < 0:
                key += self.inst._length
            if not 0 <= key < self.inst._length:
                raise IndexError("list index out of range")
            return self.inst._data[self.inst._offset + key]
        elif isinstance(key, slice):
            return self.inst[key].items
    
    def __setitem__(self, key, value):
        if isinstance(key, int):
            if key < 0:
                key += self.inst._length
            if not 0 <= key < self.inst._length:
                raise IndexError("list assignment index out of range")
            self.inst._data[self.inst._offset + key] = value

class Custom:
    def __init__(self, items, offset=0, length=None):
        # 所有实例共享的原始数据列表,仅初始化时实际存储
        self._data = items
        # 当前视图的起始偏移和长度
        self._offset = offset
        self._length = length if length is not None else len(items) - offset
        # 绑定items代理,兼容原代码的.items[]写法
        self.items = ListView(self)
    
    def __getitem__(self, key):
        if isinstance(key, int):
            # 单个元素访问直接返回对应值
            if key < 0:
                key += self._length
            if not 0 <= key < self._length:
                raise IndexError("list index out of range")
            return self._data[self._offset + key]
        elif isinstance(key, slice):
            start, stop, step = key.indices(self._length)
            # 简单实现仅支持步长为1的切片生成视图,非步长1可按需扩展
            if step != 1:
                raise NotImplementedError("Only step=1 slice is supported for view")
            # 直接共享原始_data,仅传递偏移和长度,不拷贝数据
            return Custom(self._data, self._offset + start, stop - start)

测试效果

运行你提供的测试代码:

custom = Custom([1, 2, 3, 4])
view = custom[0:2]
view.items[0] = 0
print(custom.items[0] == 0)

输出结果为True,符合预期。

补充说明

如果你不需要兼容view.items[0] = 0的写法,直接通过实例本身做下标操作(即view[0] = 0),可以省略ListView代理类,在Custom中补充__setitem__方法即可,代码会更简洁。


内容的提问来源于stack exchange,提问作者Ramen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 09:15:04