从零打造属于你的Python容器类型:全流程图解+实战案例

在日常python开发中,内置的list、dict、set等容器类型极大地方便了我们的数据管理。但如果业务出现特殊需求,标准容器无法胜任怎么办?此时就需要自定义容器,既能像内置类型一样用,也能实现个性化行为!今天带你由浅入深地掌握Python"自定义容器"的全部方法和核心原理。


一、什么是自定义容器?

自定义容器指的是:实现特定"容器协议"的自定义类,对象能像list/dict一样支持索引、for循环、len()、in、切片等操作。

你可以实现:

  • 定长队列(缓存)
  • 有效期缓存字典
  • 只读/自定义校验的有序集合
  • 支持自定义索引的数据结构
  • "伪"list/"伪"dict等任意自定义数据行为

二、最基础的容器协议:__len__、__getitem__、__setitem__

示例:仿列表的自定义容器

python 复制代码
class MyList:
    def __init__(self, data=None):
        self._data = list(data) if data else []
        
    def __len__(self):
        return len(self._data)
    
    def __getitem__(self, idx):
        print(f"访问索引 {idx}")
        return self._data[idx]
    
    def __setitem__(self, idx, value):
        print(f"将{value}赋值到索引{idx}")
        self._data[idx] = value
    
    def append(self, value):
        self._data.append(value)
python 复制代码
ml = MyList([1, 2, 3])
print(len(ml))        # 3
print(ml[1])          # 访问索引 1  \n 2
ml[1] = 100           # 将100赋值到索引1
ml.append(200)
print(list(ml._data)) # [1, 100, 3, 200]

三、进阶协议:__iter__, __contains__和切片支持

  • __iter__ 让你的容器支持 for ... in ...
  • __contains__ 支持 in 判断
python 复制代码
class MyList:
    def __init__(self, data=None):
        self._data = list(data) if data else []
        
    def __len__(self):
        return len(self._data)
    
    def __getitem__(self, idx):
        print(f"访问索引 {idx}")
        return self._data[idx]
    
    def __setitem__(self, idx, value):
        print(f"将{value}赋值到索引{idx}")
        self._data[idx] = value
    
    def append(self, value):
        self._data.append(value)

    def __iter__(self):
        return iter(self._data)
    
    def __contains__(self, item):
        return item in self._data

ml = MyList([1, 2, 3])
print(len(ml))        # 3
print(ml[1])          # 访问索引 1  \n 2
ml[1] = 100           # 将100赋值到索引1
ml.append(200)
print(list(ml._data)) # [1, 100, 3, 200]

for i in ml:
    print(i)
print(100 in ml)  # True

支持切片

要支持切片,需要同时处理 index 和 slice:

python 复制代码
   def __getitem__(self, idx):
        if isinstance(idx, slice):
            print(f"访问切片 {idx}")
            return MyList(self._data[idx])
        return self._data[idx]

四、实现字典型容器协议:__setitem__、__getitem__、__delitem__等

自定义dict-like结构:

python 复制代码
class MyDict:
    def __init__(self):
        self._d = {}

    def __setitem__(self, key, value):
        self._d[key] = value

    def __getitem__(self, key):
        return self._d[key]

    def __delitem__(self, key):
        del self._d[key]

    def __contains__(self, key):
        return key in self._d

    def keys(self):
        return self._d.keys()

    def items(self):
        return self._d.items()
        
    def values(self):
        return self._d.values()

五、更高阶设计:自定义行为与约束

比如:只读容器、自动过滤、缓存等

python 复制代码
class ReadOnlyList:
    def __init__(self, data):
        self._data = list(data)
        
    def __getitem__(self, idx):
        return self._data[idx]
        
    def __len__(self):
        return len(self._data)
        
    def __setitem__(self, idx, value):
        raise NotImplementedError("只读容器!")
        
    def append(self, value):
        raise NotImplementedError("只读容器!")

六、魔法方法一览表(小抄)

魔法方法 作用
__len__ len(obj)
__getitem__ obj[key]
__setitem__ obj[key]=value
__delitem__ del obj[key]
__iter__ for x in obj
__contains__ x in obj
__reversed__ reversed(obj)

更多见Python数据模型官方文档


如果你喜欢这篇文章,欢迎点赞、收藏和转发,更多Python干货内容敬请关注!

相关推荐
Highcharts.js20 分钟前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
神仙别闹1 小时前
基于Python实现英词语自动对齐系统
开发语言·python
螺丝钉tina1 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
老歌老听老掉牙2 小时前
圆柱端面四平面交线及其在yoz面投影的几何解析与 Python 实现
开发语言·python·平面
小天源2 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
我要见SA姐12 小时前
Chrome 扩展安全攻防实录:从权限滥用到供应链投毒
运维·人工智能·python·机器学习·自动化
2601_962885722 小时前
给 backtrader 接 A 股数据:用 AlphaFeed 喂PandasData
python
YYYing.2 小时前
【Agent系列 (十一) 】上下文工程
人工智能·python·ai·agent·上下文工程
计算机毕业编程指导师2 小时前
基于深度学习的光伏组件红外图像缺陷识别系统设计与实现
人工智能·python·深度学习·目标检测·毕业设计·课程设计·光伏
前端精髓3 小时前
langchain 短期记忆(状态)动态运行时上下文
python·langchain