overriding bool() for custom class

Question:

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)

Asked By: Ponkadoodle

||

Answers:

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
Answered By: Joe Holloway

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__
Answered By: John La Rooy

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
Answered By: IceArdor

Similar to John La Rooy, I use:

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

    def __nonzero__(self):
        return self.__bool__()
Answered By: tknickman

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

Answered By: jhp