Python Boolean Testing
00:00
To talk about Python Boolean testing, let’s begin where Booleans are used most frequently, and this is in if
statements. So, consider this if
statement. We’re going to run the function do_something()
if some expression evaluates to True
. Now, the actual expression that’s in the if
statement may not necessarily be a Boolean value, but whatever some expression evaluates to, Python will determine whether that value is truthy—which would evaluate to the Boolean True
—or if it’s falsy—which would then evaluate to the Boolean False
.
00:37
Now, any object is considered truthy unless its class defines a .__bool__()
method and the .__bool__()
method then specifies how or when the object should have a False
value, or it should specify the .__len__()
(length) method and when the .__len__()
method returns a zero value, then that evaluates to the Boolean False
.
01:01
If both the .__bool__()
method and the .__len__()
method are defined in your class, then the .__bool__()
method takes precedence.
01:11
The None
value, which is the only instance of the None
object, is considered False
. Of course, the Boolean False
value is falsy. Zero of any numeric type—like the integer 0
, the float 0.0
, and so on—they’re all considered falsy.
01:29 Empty sequences and collections—like the empty string, an empty tuple, the empty dictionary, and so on—they’re all considered falsy.
01:39
You’ve seen an example of how you can leverage the short-circuiting feature of or
to set a default value on an empty string.
01:48
Now you know that you can also do this if the string has an initial value of None
or if it’s any other object that has a value of None
.
01:57
Since None
is falsy and or
returns the second operand if the first evaluates to False
, we can also use None
to set default values.
02:07
So here’s a quick example. We’ve got this function called message()
. It takes in one parameter, msg
, initially set to None
, which means then that if message()
is called with no input, then msg
gets set a value of None
inside the function.
02:24
And all we’re doing inside the function is returning either msg
or this sort of default message, which is "This action cannot be undone!"
.
02:34
So here’s a quick example. The message()
function is called without an input, and so msg
is set to None
and so the default value of "This action cannot be undone!"
is returned.
02:45
That’s the second operand in the or
operator. Otherwise, if the message()
function is called with an input that evaluates to True
or is truthy, then that message gets returned by the function.
03:00 All right! Let’s take a look at some examples of how objects are converted to Booleans.
03:07
Let’s start by taking a look at the Boolean value of a function. Go ahead and define a function. You can call it, say, func()
. And then this is simply going to return a value of False
.
03:19
And if we check out the Boolean value of this function func()
, then we’re going to get True
. Now let’s do the same thing, say, for a class. This’ll be an Article
class and for the moment, let’s just pass on defining anything in the class.
03:37
And if we have an instance of the class, say article
,
03:41
and we check out the Boolean value of article
, then we’re going to get also True
.
03:51
Now let’s redefine the Article
class, and this time let’s define a property called .published
, and it’s going to start off with an initial value of False
. And let’s define the .__bool__()
method and so this will return the status, or the state, of the .published
property. So let’s return self.published
.
04:17
Okay. And then, why don’t you go ahead and create a new instance of this Article
class? Say, article
, and now let’s check out the Boolean value of this article
instance. Okay. So in this case, because of course the value of the .published
property is False
, then we’re going to get a False
value. Now if you go ahead and change this property .published
to a value of True
, when you now compute the Boolean value of this article
instance, you’re going to get True
. Now, that means that if you were to use this article
instance in an if
statement—so if you were to write if article
—so this is basically “If the article
has been published, then we’re going to go ahead and do something with this article
.” So in this case, we can write something like "The article has been published!"
Okay.
05:15
So this is sort of a way for you to build into your class what it means for whatever instance you’re working with to have a truth value. And so in this case, we’re going to get The article has been published!
because the .published
property has a True
Boolean value. All right!
05:33
Let’s take a look at another example with working with a class, and instead of defining a .__bool__()
method, suppose it makes more sense to define a .__len__()
(length) method for your class.
05:44
Go ahead and define a class that describes a network or a mathematical graph or a discreet graph. This class is going to have a list of vertices, and so we’re going to set that to an empty list initially, and then the .__len__()
method is going to return the number of vertices in the graph or the number of vertices in the network.
06:07
And so in this case, you’re going to return the length of the property that holds this list of vertices. Okay, so now let’s use this Graph
class. Let’s suppose that you’re using this class to model some sort of network of airports.
06:26
Let’s say airports
, and we’re going to create our Graph
.
06:32
Now, currently the airports
instance of this Graph
class—the length of the .vertices
list is 0
. So if we were to compute the Boolean value of this airports
instance, we’re going to get False
. And so here, Python is going in, computing the length of the .vertices
and in this case, it’s going to be 0
, and so that evaluates to False
. All right, now let’s suppose you were to add some airports to your graph model, and so the vertices are going to be, let’s just say, JFK, and we’re going to add, say, LAX. And then why don’t you add, also, Miami.
07:11
All right, so now the .vertices
list has a nonzero length, and so if we compute the Boolean value of airports
, we’re going to get True
, right? The length of .vertices
is nonzero, that is what Python is doing to compute the Boolean value of airports
.
07:29
And in this case, we get greater than 0
and so we get a True
value for the Boolean.
07:37
So, like you did with the article
instance, you could do the same thing for the airports model. And if the airports
instance did have airports in the .vertices
, then you would go ahead and do something with that. So if airports
is True
, meaning that the airports
instance did have some vertices or some airports, maybe you would go ahead and—let’s just try something simple—just print out what the vertices are. And in this case, we just simply get JFK, LAX, and Miami. However, if airports.vertices
, let’s say this was back to the empty list, Then if we run that exact same if
statement and print out the airports
, then because the list has a length of 0
, it evaluates to False
. And then when we run that if
statement, nothing happens. We don’t get that print statement.
08:34
Let’s take a look at one more example of a class that has both the .__len__()
method and the .__bool__()
method defined. We’re going to call this the User
class.
08:44
It’s going to be some class that keeps track of users on a website. It’s going to have a property of .active
, so whether the user is active or not, and then it’s going to keep track of the posts made by the user.
08:57
This is just going to be a list. And let’s define a length method. This will be the number of posts that the user has made on the website, so we’re going to return the length of the .posts
list.
09:14
And then we’ll also have a Boolean .__bool__()
method, and this is just going to keep track of whether the user is active or not, and so this will return the .active
property of the User
.
09:29
Okay, so we both have a .__len__()
method and a .__bool__()
method. And that should be an l
. All right, so let’s run that and let’s create a user
, so User()
.
09:44
And let’s maybe add some posts that the user has made, and so we’ll say something like "Great picture!"
or something like this. And why don’t we also add, say, "Thank you!"
. Okay, so maybe the user’s posting “Thank you!” to something on the website.
10:02
All right, let’s clear that up. Now, as you have it now, the user
has an .active
value of False
but the length of the user
is 2
, right?
10:13
So the user has made two posts, but this is an inactive user. Now, because both .__bool__()
and .__len__()
are defined, .__bool__()
takes precedence, and so if we use the user
in an if
statement, it’s going to be checking the .__bool__()
function, the .__bool__()
dunder method. And so in this case if we were to write something like if user:
, meaning that “If the user
is active,” then why don’t we go ahead and print something like "We have an active user!"
.
10:44
Whereas if the user
is not active, then we want to print something like "The user is not active!"
. Let’s go ahead and do that, so "We have an inactive user!"
.
11:00
All right. So, since you have a user that’s not active, that is what the .__bool__()
method is going to look at when you use it in any type of Boolean expression. And so in this case, we’re going to get the message that We have an inactive user!
Now, that still is the case, even though that this user
has a length of 2
.
11:20
Now, however, if you change the .active
property to True
so now we do have an active user, then if we run that same code that checks whether the user
is active or not, then in this case, we’re going to get that print statement that the user is an active user.
11:39
All right! So that’s just a quick example of how if you have both the .__len__()
and the .__bool__()
dunder methods defined on the class, the .__bool__()
method takes precedence and that’s what’s going to be checked in any type of Boolean expression involving an instance of the class. All right!
11:58 That’s the end of the last lesson. In the next lesson, we’ll summarize the contents of the video course.
Bartosz Zaczyński RP Team on March 22, 2021
@engmoh321 I’m not sure if I follow your question correctly, but let me try to break it down for you.
The bool()
function takes whatever parameter you pass to it and tries to convert it into a Boolean value, i.e., either True
or False
, according to a few rules.
If you pass one of the built-in data types, such as a number, then most values will become truthy, while only one will usually be falsy, for example:
>>> # Integers are truthy except for zero
>>> bool(42), bool(-42), bool(0)
(True, True, False)
>>> # Floats are truthy except for zero
>>> bool(3.14), bool(-3.14), bool(0.0)
(True, True, False)
>>> # Functions are always truthy
>>> def foo():
... pass
>>> bool(foo)
True
Objects such as strings or lists that have a length property are falsy only when their length is zero: (They define a special method .__len__()
, which can be tested with the len()
function.)
>>> # Strings are truthy except for the empty string
>>> bool("Hello"), bool("")
(True, False)
>>> # Collections are truthy except when they're empty
>>> bool(list()), bool(tuple()), bool(dict()), bool(set())
(False, False, False, False)
>>> bool([1]), bool((1,)), bool({1:1}), bool(set([1]))
(True, True, True, True)
Finally, your custom data types can define a special method .__bool__()
to implement truth value testing:
class User:
def __init__(self, is_admin):
self.is_admin = is_admin
def __bool__(self):
return self.is_admin
user = User(is_admin=False)
if user:
print("The admin can view private data")
else:
print("An anonymous user can't view private data")
I hope this clears it up for you.
engmoh321 on March 23, 2021
Thank you Bartosz Zaczyński. If I use function with return bool()
function will return function return value:
def foo():
return False
bool(foo())
#False
Bartosz Zaczyński RP Team on March 23, 2021
@engmoh321 Here’s what happens:
- Python calls your function and evaluates its return value:
foo()
- It passes the return value
False
to thebool()
function:bool(False)
- Since
False
is already a Boolean, the call tobool()
has no effect. - You get
False
.
engmoh321 on March 23, 2021
def foo():
return False
print(foo)
#<function foo at 0x000002020EAA53A0>
bool(foo)
#True
If print function name only without calling it return:
<function foo at 0x000002020EAA53A0>
This value (<function foo at 0x000002020EAA53A0>
) truthy string.
Bartosz Zaczyński RP Team on March 24, 2021
@engmoh321 The bool()
function converts its argument to a Boolean value and returns it, while the print()
function converts its argument to a string representation and displays it on the screen.
stehnacheric on Oct. 19, 2022
Hello, at 3.25 why does the bool(func) return true and not false if func returns false?
Leodanis Pozo Ramos RP Team on Oct. 19, 2022
@stehnacheric In this case, we’re calling bool() with the func
function object as an argument rather than with the result of calling func()
. Function objects, like many Python objects, evaluate to True
.
According to the documentation:
By default, an object is considered true unless its class defines either a
__bool__()
method that returns False or a__len__()
method that returns zero, when called with the object. Here are most of the built-in objects considered false:
- constants defined to be false:
None
andFalse
.- zero of any numeric type:
0
,0.0
,0j
,Decimal(0)
,Fraction(0, 1)
- empty sequences and collections:
''
,()
,[]
,{}
,set()
,range(0)
Become a Member to join the conversation.
engmoh321 on March 22, 2021
Thank you Cesar Aguilar. After
print(fun1, fun2, fun3)
we have the functions’ memory locations but return is string likeprint(bool("<function fun1 at 0x0000024A75F95310>"), bool('<function fun2 at 0x0000024A75F95C10>'), bool('<function fun3 at 0x0000024A75F95700>'))
or depend on dunder__bool__
method for function class I do not now if function class has dunder__bool__
method or not.If I do this:
bool()
returns the return value of function