Reputation: 257
I want to do something like this:
MyClass > 200 < 400
The class implements the __gt__()
and __lt__()
methods and they both return self
.
class MyClass:
...
def __gt__(self, value):
DoCompareStuff(self, value)
return self
def __lt__(self, value):
DoCompareStuff(self, value)
return self
...
It will do the first evaluation, MyClass > 200
, but never performs the second, MyClass < 400
. It seems like Python is doing something with the return value like making it True
or False
. Is there a way to do what I'm trying to do here?
Upvotes: 1
Views: 524
Reputation:
First of all, this code doesn't make sense:
MyClass > 200 < 400
As it expands to:
MyClass > 200 and 200 < 400
Which resolves to:
MyClass > 200
Secondly, Python has a strong concept of "truthiness" when it comes to boolean values. Which means in essence, anything that is not zero-ish is "true".
Lastly, when you have this code:
def __gt__(self, value):
DoCompareStuff(self, value)
return self
Since self
will be an object of some type, it will always, always* be true. For example both of these will evaluate to true, because you are returning self
:
10 < MyClassInstance
10 > MyClassInstance
* sometimes, except when you implement the __bool__
method. (Thanks @wim)
Upvotes: 2
Reputation: 122024
Operator chaining for comparisons (see the docs) means that
MyClass > 200 < 400
is actually evaluated as:
(MyClass > 200) and (200 < 400)
therefore no comparison between MyClass
and 400
is ever made. Instead, you want:
200 < MyClass < 400
which is evaluated as:
(200 < MyClass) and (MyClass < 400)
For a simpler example:
>>> class Demo(object):
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other
def __gt__(self, other):
return self.value > other
>>> demo = Demo(250)
>>> 200 < demo < 400
True
Note that the __lt__
and __gt__
implementations here have a Boolean return (True
or False
), rather than returning self
(which will lead to unexpected behaviour).
Upvotes: 4