乐于分享
好东西不私藏

容器协议 | 文档集合

容器协议 | 文档集合

"""任务:实现容器协议场景:自定义文档集合类"""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] = value    def __delitem__(self, key):        """支持del"""        del self.documents[key]    def __contains__(self, key):        """支持in运算符"""        return key in self.documents    def __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] = value    def __delitem__(self, key):        del self.data[key]    def __contains__(self, key):        return key in self.data    def __iter__(self):        return iter(self.data)