0

0

如何实现一个支持 getitem 和切片的自定义序列类

冷炫風刃

冷炫風刃

发布时间:2026-01-24 17:48:09

|

109人浏览过

|

来源于php中文网

原创

必须实现 __getitem__ 并处理 slice 对象,否则切片会报错;建议用 key.indices(len(self._data)) 解析切片,返回同类型实例;还需实现 __len__ 和 __iter__ 才构成完整序列。

如何实现一个支持 getitem 和切片的自定义序列类

必须实现 __getitem__ 且要处理 slice 对象

Python 的切片操作(如 obj[1:5])会直接调用 __getitem__,但传入的不是整数,而是 slice 实例。如果只支持整数索引,遇到切片就会抛 TypeError: 'slice' object is not subscriptable

实操建议:

  • __getitem__ 中用 isinstance(key, slice) 分支判断
  • 手动调用 key.indices(len(self._data))slice 映射为 (start, stop, step) —— 它自动处理负索引、越界、默认值(None)等细节
  • range(*key.indices(...)) 构造索引序列,再逐个取值或返回新序列实例(推荐)

返回值类型要匹配原序列语义

切片结果该返回什么?取决于你的类设计目标:是“视图”还是“副本”,是否可变。

常见选择:

  • 返回同类型实例(最安全):比如 MyList 切片后仍返回 MyList,需确保构造函数能接收可迭代对象
  • 返回内置 list(简单但丢失类型):适合只读工具类,但破坏了序列一致性
  • 避免返回原始内部列表引用:否则外部修改会影响内部状态,违背封装

示例片段:

def __getitem__(self, key):
    if isinstance(key, slice):
        # 假设 self._data 是 list 或其他序列
        indices = key.indices(len(self._data))
        return self.__class__([self._data[i] for i in range(*indices)])
    else:
        return self._data[key]

别忘了 __len____iter__ 才算完整序列

仅靠 __getitem__ 不足以让类被识别为 Python 序列。很多内置函数(如 len()for 循环、list())会分别查找 __len____iter__

IBM Watson
IBM Watson

IBM Watson文字转语音

下载

不实现的后果:

  • __len__len(obj)TypeError
  • __iter__for x in obj: 回退到 __getitem__ 从 0 开始调用,但若索引越界没抛 IndexError 就会无限循环

最简 __iter__ 实现就是 yield from self._data__len__ 直接返回 len(self._data) 即可。

边界情况:空序列、负步长、step ≠ 1 的切片

slice.indices() 能帮你扛住大部分边界,但要注意它返回的 rangestep 时是递减的,直接用于索引列表没问题,但如果你手动拼 <code>list,得确保下标合法(range 本身已过滤无效索引)。

容易漏掉的点:

  • 空切片(如 [5:2][1:1])→ range(*...) 为空,返回空序列即可
  • step 为负数时,start 可能大于 stop,但 range 天然支持,不用额外判断
  • 如果内部存储不支持随机访问(比如是生成器),就不能用 __getitem__ 支持切片——得换设计,比如只支持按需迭代

真正麻烦的是把自定义序列嵌套进 NumPy 或 Pandas:它们可能绕过 __getitem__ 直接查 __array__ 或调用 C 层接口,这时候光靠 Python 魔术方法不够。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

78

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

32

2026.01.31

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1902

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

656

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2387

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

47

2026.01.19

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

53

2025.09.03

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

53

2025.09.03

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号