Python 3.3+collectionsterm
collections.abc.Set
collections.abc — protocols
The abstract base class for read-only sets: implement __contains__, __iter__ and __len__ and you get &, |, -, ^, comparisons and isdisjoint.
Syntax
class MySet(collections.abc.Set):
def __contains__(self, x): ...
def __iter__(self): ...
def __len__(self): ...
The three methods buy you operators, not named methods: union(), intersection() and add() do not appear — they are the set API, not Set. The results of &, | and - are built by the classmethod _from_iterable, which calls cls(iterable), so override it if your constructor takes other arguments. Because Set defines __eq__, your class becomes unhashable; set __hash__ = Set._hash to use it as a dict key. set, frozenset, dict.keys() and dict.items() are all Sets, but dict.values() and list are not.
Examples
from collections.abc import Set
class Ordered(Set):
def __init__(self, items):
self._items = list(dict.fromkeys(items))
def __contains__(self, x):
return x in self._items
def __iter__(self):
return iter(self._items)
def __len__(self):
return len(self._items)
a, b = Ordered([1, 2, 3]), Ordered([2, 3, 4])
print(list(a & b), list(a | b), list(a - b)) # → [2, 3] [1, 2, 3, 4] [1]
print(Ordered([1, 2]) <= a, a == {1, 2, 3}) # → True True
print(hasattr(a, 'union'), a.__hash__) # → False None
from collections.abc import Set
d = {'a': 1}
print(isinstance(frozenset(), Set), isinstance(d.keys(), Set)) # → True True
print(isinstance(d.values(), Set), isinstance([], Set)) # → False False
See also
Open in the full glossarydocs.python.orgReport an inaccuracy