Understanding Null in Python
Like most programming languages, Python has a number of ways to represent null values.
Some languages use this as a pointer that points to nothing. Other times, null is used to represent when a variable is empty or to describe variables that have been instantiated but not yet defined.
With so mayn details to consider, null values can be difficult to understand. This tutorial will teach you everything you need to know about null values in Python.
Table of Contents
You can skip to a specific section of this Python null value tutorial using the table of contents below:
- What is Null?
- Assigning None to variables in Python
- Using None for Comparison
- Using None as a Value in Python
- None in Tracebacks
- Final Thoughts
What is Null?
Null means no value is defined. Null is used to represent a pointer that doesn't point to anything or when a variable or an argument is empty. In many other programming languages, Null is often defined to be 0. Java and PHP are two popular languages that use Null.
Let’s see how Null is used in PHP and Java.
PHP
<?php
$exampleVariable = NULL;
?>
Java
exampleVariable = null;
However, the concept of Null is quite different in Python as Python has None to define Null objects or variables. While None serves the same purpose as the Null, None doesn’t define 0 or any other value. None is its own object in python.
Check the examples below
exampleVariable = None
exampleVariable = None
print(type(exampleVariable))
RESULT
Assigning None to variables in Python
In other programming languages, variables can be declared without assigning an initial value to them. Also Null can only be assigned to specific types of variables. However, you can’t declare variables without assigning values as it will give an error.
See the example below.
Variable
print(Variable)
Result
In such instances, you can assign None at the variable declaration But in Python, you need to assign a value to a variable at the initial declaration and None can be assigned to any type of variable.
noneVariable = None
print(noneVariable)
RESULT
If a variable is not defined properly, it will cause a NameError. When None is declared, the variable will be a Null object. In Python, None is only equal to None. It is not equal to an empty string, the Boolean value False, or the numerical value 0.
The IF statement in the python code below demonstrates this clearly. It checks if the “noneVariable” is equal to the empty string, 0, False, or None. The IF condition only validates when the variable compares with None object.
noneVariable = None
if noneVariable == "":
print("None is Equal to an empty string")
elif noneVariable == 0:
print("None is Equal to 0")
elif noneVariable == False:
print("None is Equal to False")
elif noneVariable == None:
print("None is Equal to None")
RESULT
Understanding more about None
Any function without a proper return statement returns None. In Python, None object is so ubiquitous in REPL, it won’t print None unless the user explicitly tells it to. The following examples show how None is identified in Python.
Python None as a return value.
def examplefunction():
pass
examplefunction()
print(examplefunction())
RESULT
In this instance, when a function is created with no explicit return value, Python returns None as the result. Because Python REPL won’t print None unless explicitly declared we use the print statement to identify the output.
print()
print(None)
print(print('Hello'))
RESULT
In the python print() function, there is no return value to the function itself. Because of this, the first print() statement in the above example returns no explicit value. When the None object passes to the The second print statement, it returns None. Finally, in the nested print() statement the print(‘Hello’) returns the Hello string as the result. But as the print statement itself has no explicit return object, it will be shown as None.
None to identify missing or default parameters.
Let's look at the docs of list.sort function.
help(list.sort)
RESULT
As you can see in the output, None is assigned to the “key” parameter. Although the key parameter is required here, it is not provided. So, it indicates None as the default parameter.
Using None for Comparison
The identity operators and equality operators can be used to test whether two variables are referring to the same object. So, you can use them to test when a variable has been assigned as None. Both the equality operator(“==”) or the identity operator “is” can be used to check this.
# Equality Operator
x = None
if x == None:
print("x is equal to None")
else:
print("x is equal to None")
# Identity Operator
y = None
if y is None:
print("y is equal to None")
else:
print("y is equal to None")
RESULT
However, there is a difference between the identity operator “is” and the equality operator “==”.
The identity operator checks if both the operands are referring to the same object while the equality operator checks if both operands are equal in value. The below examples demonstrate how these operations can be used properly in comparison tasks.
Check if an object is None
import re
stringvalue = "Barry"
# Check if "stringvalue" matches "Harry"
match = re.match(stringvalue, "Harry")
# Check if match is a None object
if match is None:
print("item do not match")
else:
print("item do match")
RESULT
In this example, we check if two values match with each other. . The match function will return a None object if the two values passed to it do not match. Then we use identity operators to validate the results.
If you want to correctly verify a value is a None object, using identity operators is the most optimal as equality operators can be fooled when other user defined objects that override the value. The following example shows this scenario.
class CheckComparison:
def __eq__(self, other):
return True
x = CheckComparison()
# Equality Operator
print(x == None)
# Identity Operator
print(x is None)
RESULT
The equality operator has been overridden by the object equality (eq) of the class CheckComparision and this results in an incorrect output. As identity operators cannot be overridden, the intended result is displayed.
Using None as a Value in Python
In python, None can be added to a set as an item. Similarly, it can be used as a function parameter.
To illustrate that, we will check the following example. We create an empty class that will be used as the signal not to append. Then create the function “addto_list” with two parameters to add an element to a given “set”.
# To be used as a signal not to append
class AddNone:
pass
# Main Function
def addto_list(new_element=AddNone, initial_set=None):
if initial_set is None:
initial_set = {}
if new_element is not AddNone:
initial_set.add(new_element)
return initial_set
# Initial Set
colours = {"pink", "purple", "blue", "green", "yellow", "orange"}
print(addto_list(initial_set=colours))
RESULT
As we have defined default values for each parameter, it is not necessary to pass both values for each parameter. We pass the “colours” set as the initial set. This results in output returning the “colours” set back as it's not a None object. Please note that because sets are unordered, the resulting set shows the items in a random order.
# To be used as a signal not to append
class AddNone:
pass
# Main Function
def addto_list(new_element=AddNone, initial_set=None):
if initial_set is None:
initial_set = {}
if new_element is not AddNone:
initial_set.add(new_element)
return initial_set
# Initial Set
colours = {"pink", "purple", "blue", "green", "yellow", "orange"}
print(addto_list(None, initial_set=colours))
RESULT
In the above instance, we pass both parameters. But for the newelement, we pass a None object, and for initialset, we pass the colours set. As you can see the None object is added to the set. When None is a valid input item, it can be added to a set.
None in Tracebacks
Let’s have a look at one of the common issues related to None. If you see an error like “AttributeError: NoneType object has no attribute …”, it means you have tried to use None keyword in an incorrect way. One of the common reason for it could be calling a method on a variable that is defined to be Null.
Let us consider the following examples.
# fruits set with items
fruits = {"cherry", "banana", "apple"}
fruits.add("orange")
print(fruits)
RESULT
In this instance, we create a set called “fruits”, and add another value called “orange”. Here, the code executes successfully as the Python sets contain the add method. However, the following code won’t be successful
# fruits as a None Object
fruits = None
fruits.add("strawberry")
print(fruits)
RESULT
In the above example the “fruits” variable is declared as a None type object. As there is no add method associated with None object this results in an error.
So next time, when you get a traceback like this in your code, first, check the attribute that raised the error. In the above example, it was the add() method. Then you can find the object on which the method was called. After figuring out how the object became None, you can work on fixing the code.
Final Thoughts
All in all, as a first-class citizen in python, None plays a significant role in programming. None can be used for various tasks such as checking missing values, comparing results. Being an immutable keyword None is a solid choice for parameters in functions over mutable types.