86

Why doesn't this work as one may have naively expected?

class Foo(object):
    def __init__(self):
        self.bar = 3
    def __bool__(self):
        return self.bar > 10

foo = Foo()

if foo:
    print 'x'
else:
    print 'y'

(The output is x)

1

3 Answers 3

85

For Python 2-3 compatibility, add a line after the class definition block to alias the method:

class Foo(object):
    ...

Foo.__nonzero__ = Foo.__bool__

or include the alias directly in the class definition:

class Foo(object):
    def __bool__(self):
        ...

    __nonzero__ = __bool__

Of course this would also work the other way around, but I think the name __nonzero__ is just a legacy of the original C-ishness of Python's interpretation of objects as truthy or falsy based on their equivalence with zero. Just add the statement above and the code will work with regardless of the version of Python (and the __nonzero__ definition can be dropped when support for 2.x is no longer needed).

1
  • Where would these insertions go? I'm guessing the first could go immediately after the line return self.bar > 10 (indented 0 spaces) and that the second could go immediately before the line def __init__(self): (indented 4 spaces). Is that correct? Or would the second have to go after the __bool__ definition?
    – Beetle
    Commented Sep 22, 2015 at 11:24
76

The __bool__ method is used only in Python 3.x. For 2.x, use __nonzero__.

3
  • 1
    right, strange but true. good to see they changed implementation to the 'one obvious way to do it'
    – wim
    Commented Nov 22, 2011 at 6:18
  • 7
    @wim: Not too strange. The __nonzero__() method name considerably predates the introduction of the type bool in Python. Before bool, the just use the integers 0 and 1. Commented Nov 22, 2011 at 23:02
  • 3
    @SvenMarnach: You guys had 0 and 1? Dilbert ;-)
    – JS.
    Commented Oct 17, 2014 at 0:57
27

Because the corresponding special method is called __nonzero__() in Python 2, and not __bool__() until Python 3.

Not the answer you're looking for? Browse other questions tagged or ask your own question.