Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

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

Avatar image for engmoh321

engmoh321 on March 22, 2021

def fun1():
    pass

def fun2():
    return False

def fun3():
    return True

print(fun1, fun2, fun3)

print(bool("<function fun1 at 0x0000024A75F95310>"), bool('<function fun2 at 0x0000024A75F95C10>'), bool('<function fun3 at 0x0000024A75F95700>'))

Thank you Cesar Aguilar. After print(fun1, fun2, fun3) we have the functions’ memory locations but return is string like print(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:

print(bool(fun1()), bool(fun2()), bool(fun3()))

bool() returns the return value of function

Avatar image for Bartosz Zaczyński

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.

Avatar image for engmoh321

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
Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on March 23, 2021

@engmoh321 Here’s what happens:

  1. Python calls your function and evaluates its return value: foo()
  2. It passes the return value False to the bool() function: bool(False)
  3. Since False is already a Boolean, the call to bool() has no effect.
  4. You get False.
Avatar image for engmoh321

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.

Avatar image for Bartosz Zaczyński

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.

Avatar image for stehnacheric

stehnacheric on Oct. 19, 2022

Hello, at 3.25 why does the bool(func) return true and not false if func returns false?

Avatar image for Leodanis Pozo Ramos

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 and False.
  • 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.