Python中继承set类的现代方式 自定义集合类的最优实现方案
自定义类set对象的主流实现方案
与UserDict对等的set实现
Python标准库提供了collections.UserSet作为set对应的用户自定义包装类,定位和UserDict、UserList完全一致,是当前Python 3.10+版本的首选方案。
和直接继承内置set相比,UserSet规避了C实现内置类型的常见问题:内置set的很多原生方法会绕过Python层面覆写的逻辑,比如覆写add()后调用update()可能不会触发自定义add()逻辑,而UserSet是纯Python实现的包装类,内部持有一个原生set实例,所有方法调度都走Python层,自定义覆写的逻辑可以全局生效,也可以随意添加额外实例变量。
兼容旧Python版本的实现方案
如果需要支持Python 3.10以下版本,主流做法是继承collections.abc.MutableSet抽象基类,仅需要实现5个基础方法,就能自动获得所有原生set的标准功能:
- 必须手动实现的抽象方法:
__contains__、__iter__、__len__、add、discard - 剩余的
pop、clear、update、union、issubset等全部set标准方法都会由抽象基类自动生成,且会调用你实现的基础方法,保证自定义逻辑统一生效。
实现示例
Python 3.10+ 基于UserSet的实现
from collections import UserSet class TaggedSet(UserSet): def __init__(self, iterable=None, *, tag=None): super().__init__(iterable) # 自定义额外实例变量 self.tag = tag # 覆写add方法添加校验逻辑 def add(self, item): if not isinstance(item, int): raise TypeError("仅支持添加整数元素") super().add(item)
Python 3.10- 基于MutableSet的实现
from collections.abc import MutableSet class TaggedSet(MutableSet): def __init__(self, iterable=None, *, tag=None): self._storage = set(iterable or []) # 自定义额外实例变量 self.tag = tag def __contains__(self, item): return item in self._storage def __iter__(self): return iter(self._storage) def __len__(self): return len(self._storage) def add(self, item): if not isinstance(item, int): raise TypeError("仅支持添加整数元素") self._storage.add(item) def discard(self, item): self._storage.discard(item)
两种实现都完全兼容原生set的所有操作,自定义逻辑和额外实例变量都可以正常使用。
内容的提问来源于stack exchange,提问作者Mert Mint
相关产品推荐
相关产品推荐

