[RH] > > How about adding some mixins to simplify the > > implementation of some of the fatter interfaces? [GvR] > Can you suggest implementations for these, to be absolutely clear what > you mean? -- snip -- > What if the "natural" thing to implement is __le__ instead of __lt__? > That's the case for sets. Or __gt__ (less likely)? Yes. Here is some code --------------------------- class CompareMixin: """ Given an __eq__ method in a subclass, adds a __ne__ method Given __eq__ and __lt__, adds !=, <=, >, >=. If supplied, takes advantage of __lte__ for speed. """ def __eq__(self, other): raise NotImplementedError def __ne__(self, other): return not (self == other) def __lt__(self, other): raise NotImplementedError def __lte__(self, other): return self < other or self == other def __gt__(self, other): return not (self <= other) def __gte__(self, other): return not (self < other) ## Example from sets import mixins class BaseSet(object, mixins.CompareMixin): """Common base class for mutable and immutable sets.""" __slots__ = ['_data'] # . . . def issubset(self, other): """Report whether another set contains this set.""" self._binary_sanity_check(other) if len(self) > len(other): # Fast check for obvious cases return False otherdata = other._data for elt in self: if elt not in otherdata: return False return True def __eq__(self, other): self._binary_sanity_check(other) return self._data == other._data def __lt__(self, other): self._binary_sanity_check(other) return len(self) < len(other) and self.issubset(other) __le__ = issubset # optional, but recommended for speed. # Example where gt is the most natural implementation class Anyhoo(CompareMixin): __eq__ = someBigEqualityTest __gt__ = someBigComplexOrderingFunction def __lt__(self, other): return not(self>other or self==other) [RH] > > class MappingMixin: > > """ > > Given __setitem__, __getitem__, and keys, > > implements values, items, update, get, setdefault, len, > > iterkeys, iteritems, itervalues, has_key, and __contains__. > > > > If __delitem__ is also supplied, implements clear, pop, > > and popitem. > > > > Takes advantage of __iter__ if supplied (recommended). [GvR] > Does that mean that if you have __iter__, you don't use keys()? In > that case it should implement keys() out of __iter__. Maybe this > should be required. Not really. keys() is always required. If __iter__ is supplied, then things like iterkeys(), iteritems(), and itervalues() get computed from __iter__ rather than keys(). My thought on using keys() as part of the minimum specification is that database style interfaces always supply some type of list method. For instance, shelve can be instantly widened with the mixin, no other coding is required. OTOH, I'm not glued to the idea of using keys() as part of the minimum spec. [RH] > > Takes advantage of __contains__ or has_key if supplied > > (recommended). > > """ [GvR] > Let's standardize on __contains__, not has_key(). I guess you could > provide __contains__ as follows: Makes sense. [RH] > > The idea is to make it easier to implement these interfaces. > > Also, if the interfaces get expanded, the clients automatically > > updated. [GvR] > A similar thing for sequences would be useful too, right? Hmm, listing and concatenation beget repetition; len() and __getitem__() beget slicing. iteration and __cmp__ beget min(), max() For mutable sequences, supplying __setitem__ begets appending, extending, and slice assignment. Supplying __delitem__ begets pop(), remove() and slice deletion. For overachivers, the above are all that are needed for sort(), reverse(), index(), insert(), and count() Would you like me to create a mixin module and put it in the sandbox? Raymond Hettinger
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4