overriding bool() for custom class

PythonClassCastingBooleanPython 2.x

Python Problem Overview


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)

Python Solutions


Solution 1 - Python

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 - Python

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 - Python

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 - Python

Similar to John La Rooy, I use:

class Test(object):
    def __bool__(self):
        return False

    def __nonzero__(self):
        return self.__bool__()

Solution 5 - Python

Solution 6 - Python

[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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPonkadoodleView Question on Stackoverflow
Solution 1 - PythonJoe HollowayView Answer on Stackoverflow
Solution 2 - PythonJohn La RooyView Answer on Stackoverflow
Solution 3 - PythonIceArdorView Answer on Stackoverflow
Solution 4 - PythontknickmanView Answer on Stackoverflow
Solution 5 - PythonIgnacio Vazquez-AbramsView Answer on Stackoverflow
Solution 6 - PythonjhpView Answer on Stackoverflow