1

Sorry if this hasn't been asked before because it's obvious to anyone with any form of training in Python. I spent most of my days programming in Java and I was wondering about this thing I take to be an idiosyncrasy in Python. I was messing around with

this=bool
if(this==True):this="big"
print(this)

Not surprisingly, I received a generic type declaration as output because that would indeed be big if True.

<class 'bool'>

Then I used my limited Java comprehension to determine that I could simplify the expression more, it's a conditional, right? Those are made for Boolean types.

this=bool
if(this):this="big"
print(this)

Then I almost laughed out loud but it was mirth tinged with terror

big

It makes sense that "this" is "less falsy" than "this==True", which is False with a capital F, but I still didn't think it should evaluate as True. Besides, truthy and falsy seem to be good enough in other cases to produce the expected result. So what makes an empty Boolean truthy?

My first thought was it must be just checking to see if "this" exists. So I removed the declaration in the first line, expecting to find "if([something that doesn't exist]):" would be skipped. Instead it threw an error. If the simple fact of its existence evaluates as True, shouldn't its nonexistence simply evaluate to False? What's the point of a functionality in which an initialized (empty) value evaluates to true if an uninitialized value doesn't return false? I thought I understood after reading this answer and indeed my first thought was, "Oh, it must just be checking to see if 'this' exists at all." Then I typed if(this is not None): as well as if(this!=None): and got "big" as the output again, suggesting that "this" is None.

Then, almost in a fit of panic, I typed

this=bool
if(this==None):this="big"
if(this==True):this="big"
if(this==False):this="big"
print(this)

and, as you may have guessed, failed

<class 'bool'>

Surely a Boolean must be one of these "three"? Please don't tell me I've discovered a "fourth" Boolean value, I couldn't handle that kind of notoriety.

The problem (I think) I have with all this is that removing the initialization of 'this' in the first line causes an error, and not a false case in the if statement. If "if(x):" is executed when x exists, then shouldn't a non-existent "x" pass and just skip over that statement? Why not leave the Boolean if functionality from Java and just force us to check if x is not null in that case?

reflektor
  • 21
  • 8
  • 1
    Possible duplicate of [What is Truthy and Falsy in python? How is it different from True and False?](https://stackoverflow.com/questions/39983695/what-is-truthy-and-falsy-in-python-how-is-it-different-from-true-and-false) – UnholySheep Dec 18 '18 at 23:13
  • Your examples are hard to follow, they are not valid Python. Please provide a [mcve] – juanpa.arrivillaga Dec 18 '18 at 23:14
  • 1
    But, `this=bool` assigns the *class `bool`* to the variable `this`. All class objects are Truthy. – juanpa.arrivillaga Dec 18 '18 at 23:14
  • @juanpa.arrivillaga: Well, classes with weird metaclasses need not be true. But yes, in general your statement holds. – ShadowRanger Dec 18 '18 at 23:17
  • 3
    In Java try to do this with `Object this = Boolean.class;` and see if `this.equals(true)`. That's the equivalent of what you are doing in that code. – Bakuriu Dec 18 '18 at 23:18
  • 1
    "What's the point of a functionality in which an initialized (empty) value evaluates to true if an uninitialized value doesn't return false?" At no point did you test this. The values you're testing are always initialized. If they weren't, it would raise `NameError` (at global scope) or `UnboundLocalError` (at function scope), they wouldn't silently evaluate as truthy or falsy. – ShadowRanger Dec 18 '18 at 23:20
  • 1
    Furthermore there are no uninitialized values in Python – juanpa.arrivillaga Dec 19 '18 at 02:16
  • "I removed the declaration in the first line, expecting to find "if([something that doesn't exist]):" would be skipped. Instead it threw an error." I didn't expect it to work but I did test it. It is a NameError as you say. Uninitialized values don't exist anywhere. – reflektor Dec 19 '18 at 03:23

4 Answers4

1

bool isn't a boolean, it's a class (just like int, str etc.). Classes are always truthy.

I think you meant to write this = bool() (which is the same as this = False - there's no such thing as an "empty" boolean).

sepp2k
  • 363,768
  • 54
  • 674
  • 675
1

I don't understand what you're doing here. You're taking the class bool and checking if it is exactly equal to True. Well, no of course it isn't, True is an instance of bool, a class isn't exactly equal to its instances. It's not equal to False or None either. But that doesn't stop it from being true in a Boolean context, because it's not empty.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
0

bool is a builtin class. You are assigning this to the bool class, making it never equal True. When you type if(this), this is being automatically converted to a boolean so it can be evaluated in the if statement. Classes are always converted to True rather than False, which is why the if statement executes.

Pika Supports Ukraine
  • 3,612
  • 10
  • 26
  • 42
  • So there's a distinction between a bool and a Boolean...if I understand correctly, putting `this` (a class object) in an `if` statement forces a boolean type to be cast to it? – reflektor Dec 19 '18 at 03:28
  • @reflektor no, they're the same thing. And yes, putting `this` in an if statement casts it to a `bool`. – Pika Supports Ukraine Dec 19 '18 at 05:24
0

Simply put, in general, you cannot say that if x has the same meaning as if x == True in Python. Their result depends on how x's methods __bool__ and __eq__ are defined, respectively.

For classes themselves, like bool or int (i.e. the type, not an object of that class), __bool__ is defined to always return True; while the comparison against True returns False.

Therefore:

if int == True: print("NOT printed")
if int: print("printed")
if bool(int): print("printed") # equivalent to the previous one
Acorn
  • 24,970
  • 5
  • 40
  • 69
  • So it's not checking if `this` exists, it's checking to see if there is such thing as `bool`? – reflektor Dec 19 '18 at 03:34
  • 1
    @reflektor no, python objects implement a `__bool__` method that determines what `bool(som_object)` will return, and *that's* what determines truthiness. Moreover, it will also check if `__len__` returns 0, as a special case, so empty containers get evaluated as falsy. – juanpa.arrivillaga Dec 19 '18 at 04:48