容器协议 | 文档集合
"""任务:实现容器协议场景:自定义文档集合类"""class DocumentCollection:"""文档集合"""def __init__(self):self.documents = {}def __len__(self):"""支持len()"""return len(self.documents)def __getitem__(self, key):"""支持[]读取"""return self.documents[key]def __setitem__(self, key, value):"""支持[]赋值"""self.documents[key] = valuedef __delitem__(self, key):"""支持del"""del self.documents[key]def __contains__(self, key):"""支持in运算符"""return key in self.documentsdef __iter__(self):"""支持for循环"""return iter(self.documents)# 测试collection = DocumentCollection()collection["doc1"] = "Content 1"collection["doc2"] = "Content 2"assert len(collection) == 2assert "doc1" in collectionassert collection["doc1"] == "Content 1"del collection["doc1"]assert "doc1" not in collectionfor doc_id in collection:print(f"{doc_id}: {collection[doc_id]}")
一、场景
文档库管理,自己做了一个文档仓库,存文档 ID + 内容,可以增删改查、判断是否存在,可以遍历所有文档。
二、个人理解/最初卡在哪里
1、在 def __len__(self) 中,自己写代码手动造了一个 len () 功能,实际上不需要,字典本身自带 len (),可以直接用 len(self.documents)。
几乎所有容器类型都可以直接用 len (xxx),包括字符串、列表、元组、字典、集合。不过自己创建的类,默认不能用 len ():
classDocumentStore:def __init__(self):self.documents = {}store = DocumentStore()len(store) # 报错
需要加 len 方法,对象才能用 len ():
class DocumentStore:def __init__(self):self.documents = {}def __len__(self):return len(self.documents)store = DocumentStore()len(store)
2、__iter__方法的含义
def __iter__(self):return iter(self.documents)
作用:让对象能被 for 循环遍历。
3、为什么要自己写这些方法?因为这是在自定义容器。__xxx__ 是 Python 固定协议名,需要这么写。这些方法里,赋值不用 return,判断、迭代、查询必须 return。
三、代码中的关键洞察
代码中写的所有方法,都是字典做的,字典功能很强大。
四、关键代码/可复用片段
class 自定义容器:def __init__(self):self.data = {} # 内部用字典存数据def __len__(self):return len(self.data)def __getitem__(self, key):return self.data[key]def __setitem__(self, key, value):self.data[key] = valuedef __delitem__(self, key):del self.data[key]def __contains__(self, key):return key in self.datadef __iter__(self):return iter(self.data)
夜雨聆风