overriding bool() for custom class
Solution 1
Is this Python 2.x or Python 3.x? For Python 2.x you are looking to override __nonzero__
instead.
class test:
def __nonzero__(self):
return False
Solution 2
If you want to keep your code forward compatible with python3 you could do something like this
class test:
def __bool__(self):
return False
__nonzero__=__bool__
Solution 3
If your test
class is list-like, define __len__
and bool(myInstanceOfTest)
will return True
if there are 1+ items (non-empty list) and False
if there are 0 items (empty list). This worked for me.
class MinPriorityQueue(object):
def __init__(self, iterable):
self.priorityQueue = heapq.heapify(iterable)
def __len__(self):
return len(self.priorityQueue)
>>> bool(MinPriorityQueue([])
False
>>> bool(MinPriorityQueue([1,3,2])
True
Solution 4
Similar to John La Rooy, I use:
class Test(object):
def __bool__(self):
return False
def __nonzero__(self):
return self.__bool__()
Solution 5
[this is a comment to the answer from @john-la-rooy but I cannot comment yet :) ]
For Python3 compatibility you can do (I was looking for this)
class test(object):
def __bool__(self):
return False
__nonzero__=__bool__
only problem is that you need to repeat the __nonzero__ = __bool__
everytime you change __bool__
in subclasses. Otherwise __nonzero__
will be kept from the superclass. You can try
from builtins import object # needs to be installed !
class test(object):
def __bool__(self):
return False
__nonzero__=__bool__
which should work (not confirmed) or write a metaclass :) yourself.
Ponkadoodle
Updated on July 09, 2022Comments
-
Ponkadoodle almost 2 years
All I want is for bool(myInstance) to return False (and for myInstance to evaluate to False when in a conditional like if/or/and. I know how to override >, <, =)
I've tried this:
class test: def __bool__(self): return False myInst = test() print bool(myInst) #prints "True" print myInst.__bool__() #prints "False"
Any suggestions?
(I am using Python 2.6)
-
Ponkadoodle over 10 yearsThat's handy. Thanks for this alternate solution.
-
TrinitronX over 9 yearsThanks for this... I was looking for a way to test the
__nonzero__
class method for testingFalse
here -
jhp over 7 yearsOr use the approach from tknickman to avoid this issue. It will add another function call though!
-
Callam Delaney almost 6 yearsThis is actually the best solution as it is compatible with both Python3 and Python2 to my knowledge. Even if it is not an iterable you could implement something to mock it.
-
IceArdor over 5 years
__nonzero__ = __bool__
is the preferable way of aliasing__bool__
because it's less code (quicker to read, less to maintain), less likely to hide a bug (what happens if__bool__
later becomes an async function?), but more importantly 1 less stack frame for a frequently called function that's also implicit! The difference here is whether you're defining 2 functions or just 1 function that's referenced twice. -
Leo Ufimtsev almost 5 yearsIt would be of benefit to mention that bool is python3 and code to make a class more portable across python2/3 as mentioned by John below.
-
Leo Ufimtsev almost 5 yearsThe nonzero__=__bool seems to how an error in python 2 because bool is not defined.
-
Zhang Fan over 3 years@LeoUfimtsev have you moved "__nonzero__=__bool__" to a smaller line number than "def __bool__(self):" ? in that case it is undefined, written order matters here.
-
LMCuber over 2 yearsWouldn't this create a class variable instead of an instance variable?