15

I want to create a class MyClass where bool(MyClass) returns False. Is it possible?

I want this behavior with the class itself, not objects of that class. For objects of that class I know that I can just return False in __bool__(self).

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
Eduardo
  • 185
  • 6
  • 13
    Would you satisfy our curiosity by explaining what it will be good for? – Ned Batchelder May 27 '18 at 18:27
  • 6
    @Eduardo I provided an answer, in exchange I too would like to know why you need that. Just out of curiosity :) – Olivier Melançon May 27 '18 at 18:34
  • Related: [How to create a custom string representation for a class object?](//stackoverflow.com/q/4932438) Same problem, different dundermethod. – Aran-Fey May 27 '18 at 18:42
  • 5
    Thank you for answering. The main thing is that I just wanted to understand the language better. I was trying something similar, trying to set `__metaclass__` inside the class body, but this does not work. I also wanted to experiment using a class as a null object, as in the null object design pattern (please don't bash me for how hacky this may be) – Eduardo May 27 '18 at 19:00
  • Luckily Python already has `None` as the null object. – Ned Batchelder May 27 '18 at 19:11
  • 2
    @Eduardo in Python3, you define the metaclass with the `metaclass=...` syntax, `__metaclass__` is only for Python2. Also, `None` is an instance of the `NoneType` class. So it's not a class. And in particular `bool(type(None))` is `True`. And finally don't worry, no bashing, toying with metaclass is fun. – Olivier Melançon May 27 '18 at 20:12
  • 6
    "Please notice also that I am not interested in discussions about why anyone would want to do that, or if it is or not a good [practice]." And that is why this is a bad question. The proper response to finding yourself doing something this utterly insane is to take several steps back and rethink the design. God have mercy on whoever has to read this code. – jpmc26 May 27 '18 at 22:42
  • Thank you for your concern, @jpmc26. I spared god the trouble of having mercy on people other than myself in this case. As I said already, I'm experimenting with the language to understand it better. – Eduardo May 28 '18 at 16:36
  • @Eduardo Learning what features are available in a language is comparatively easy. Learning the normal, expected, natural usages of those features and how to approach problems while limiting yourself to those usages is both much harder and a much more valuable investment of time. I can tell you from experience that putting that limit on yourself is the biggest single thing you can do to improve the quality of your code. At the *very* least you should not discourage such discussions; doing so can only hurt future readers. – jpmc26 May 28 '18 at 22:49
  • @jpmc26 I really feel bad somehow for being the guy that discouraged such discussion, as that is far from my usual behavior. The thing is that I really tried to avoid was to get a huge discussion about 'why' and no real answer of 'how'. Having the kind answer from Oliver, I definitely don't mind the extra discussion. – Eduardo May 28 '18 at 23:39

1 Answers1

31

To define the __bool__ method used by a class, not its instances, you need to modify its class. You do that by writing a metaclass.

class FalseMeta(type):
    def __bool__(self):
        return False

class MyClass(metaclass=FalseMeta):
    pass

print(bool(MyClass))  # False
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
  • 3
    For the reference of anyone who comes here looking for a Python 2 solution, [this](http://python-future.org/compatible_idioms.html#metaclasses) is the equivalent metaclass syntax in Python 2, and you would use `__nonzero__` rather than `__bool__` – Silvio Mayolo May 27 '18 at 19:45