以修改 Set 方法的方式子类化 Set 的最简单方法?
Simplest way to subclass Set in a way that modifies Set methods?
我想对 Python 中的集合进行子类化,使其表现得尽可能像常规集合,并进行一些小的修改,如下所示。
from typing import Iterable, Any
from collections.abc import MutableSet
class MSet(MutableSet):
""" Set with a filename attribute """
def __init__(self, fname: str, iterable: Iterable = None):
self._fname = fname
if iterable is None:
self.elements = set()
else:
self.elements = set(iterable)
def __repr__(self) -> str:
return f"NAME:{self._fname}; VALUE:{self.elements}"
def __contains__(self, value: Any) -> bool:
return value in self.elements
def __iter__(self) -> Iterable:
return iter(self.elements)
def __len__(self) -> int:
return len(self.elements)
def add(self, value: Any) -> None:
self.elements.add(value)
def discard(self, value: Any) -> None:
self.elements.discard(value)
@property
def filename(self) -> str:
return self._fname
这很好,但我希望能够实现双下法
__le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__, __sub__, __xor__,
isdisjoint, __ior__, __iand__, __ixor__, and __isub__
仅当两个 MSet 实例共享相同的“self._fname”时才有效。换句话说,如果我想比较 mset_a 和 mset_b,它们的文件名为“a.txt”和“b.txt”,我需要以下内容:
mset_a = MSet("a.txt", [1, 2, 3])
mset_b = MSet("b.txt", [2, 3, 4])
mset_a & mset_b # raise exception
我该如何实施?
您需要实现__and__
方法:
def __and__(self, other):
if self.filename != other.filename:
raise Exception()
return self.elements & other.elements
我想对 Python 中的集合进行子类化,使其表现得尽可能像常规集合,并进行一些小的修改,如下所示。
from typing import Iterable, Any
from collections.abc import MutableSet
class MSet(MutableSet):
""" Set with a filename attribute """
def __init__(self, fname: str, iterable: Iterable = None):
self._fname = fname
if iterable is None:
self.elements = set()
else:
self.elements = set(iterable)
def __repr__(self) -> str:
return f"NAME:{self._fname}; VALUE:{self.elements}"
def __contains__(self, value: Any) -> bool:
return value in self.elements
def __iter__(self) -> Iterable:
return iter(self.elements)
def __len__(self) -> int:
return len(self.elements)
def add(self, value: Any) -> None:
self.elements.add(value)
def discard(self, value: Any) -> None:
self.elements.discard(value)
@property
def filename(self) -> str:
return self._fname
这很好,但我希望能够实现双下法
__le__, __lt__, __eq__, __ne__, __gt__, __ge__, __and__, __or__, __sub__, __xor__,
isdisjoint, __ior__, __iand__, __ixor__, and __isub__
仅当两个 MSet 实例共享相同的“self._fname”时才有效。换句话说,如果我想比较 mset_a 和 mset_b,它们的文件名为“a.txt”和“b.txt”,我需要以下内容:
mset_a = MSet("a.txt", [1, 2, 3])
mset_b = MSet("b.txt", [2, 3, 4])
mset_a & mset_b # raise exception
我该如何实施?
您需要实现__and__
方法:
def __and__(self, other):
if self.filename != other.filename:
raise Exception()
return self.elements & other.elements