Python 3.3+collectionsпонятие
collections.abc.Set
collections.abc — протоколы
Абстрактный класс неизменяемого множества: реализуйте __contains__, __iter__ и __len__ — и получите &, |, -, ^, сравнения и isdisjoint.
Синтаксис
class MySet(collections.abc.Set):
def __contains__(self, x): ...
def __iter__(self): ...
def __len__(self): ...
Три метода дают операторы, но не именованные методы: union(), intersection() и add() у вашего класса не появятся — это API set, а не Set. Результаты &, | и - строятся через classmethod _from_iterable, который зовёт cls(iterable): если конструктор принимает другие аргументы, его нужно переопределить. Определив __eq__, класс теряет хешируемость; для словарных ключей нужен __hash__ = Set._hash. Set — это и set, и frozenset, и dict.keys()/dict.items(), но не dict.values() и не list.
Примеры
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
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности