Top and Bottom Values [PEP: 326]
Steven D'Aprano
steve at REMOVE.THIS.cybersource.com.au
Wed Sep 27 10:32:54 EDT 2006
On Wed, 27 Sep 2006 13:37:40 +0000, Paul McGuire wrote:
> Here's a little more refined version of my previous post:
>
> class StubbornInt(int):
> def invariantOp(self,other):
> return self
> __add__ = invariantOp
> __sub__ = invariantOp
[snip rest of code]
> import sys
> Top = StubbornInt(sys.maxint)
Top shouldn't need to depend on a specific integer value, but then it is
easy enough to subclass StubbornInt.
However, there is a more serious problem with your definition of Top:
>>> Top > sys.maxint+1
False
But Top is supposed to bigger than everything, right?
Okay, let's fix it:
class FixedTop(StubbornInt):
def __init__(self):
super(FixedTop, self).__init__(sys.maxint)
self.name = 'Top'
def _bigger(self, other):
# Top is bigger than everything
return True
def _smaller(self, other):
# Top is smaller than nothing
return False
__lt__ = __le__ = _smaller
__gt__ = __ge__ = _bigger
Let's test it out:
>>> Top = FixedTop()
>>> Top > 45
True
>>> Top > sys.maxint
True
>>> Top > 2L**512
True
>>> Top > None
True
>>> Top > "hello"
True
So far so good.
However, the downside of rolling your own Top is the risk that one day
you'll have something like this:
class Funny:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def __gt__(self, other):
return len(str(self)) > len(str(other))
and then you'll have problems:
>>> bottom = Funny("Bottom")
>>> Top > bottom
True
>>> bottom > Top
True
As far as I can see, the only way to avoid edge cases like this is for Top
(and Bottom) to be built-ins that are special-cased by Python.
--
Steven.
More information about the Python-list
mailing list