reflektor
reflektor

Reputation: 21

Why is "if(x)" different from "if(x==True)" in Python?

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?

Upvotes: 1

Views: 1357

Answers (4)

Acorn
Acorn

Reputation: 26066

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

Upvotes: 0

Picachieu
Picachieu

Reputation: 3782

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.

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599490

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.

Upvotes: 1

sepp2k
sepp2k

Reputation: 370102

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

Upvotes: 1

Related Questions