If you’ve worked with other programming languages such as C or Java, you’re familiar with the concept of null. It is used in many languages to represent a pointer that doesn’t point to anything, indicate that a variable is empty, or indicate default parameters that haven’t been supplied yet. In such languages, null is frequently defined as 0, however null in Python is different.
The keyword None is used in Python to define null objects and variables. While None serves some of the same functions as null in other languages, it’s an entirely different animal. None is determined to be 0 or any additional value in Python because it is the null value. None is an object, Python!
We’ll teach you how to use the None keyword to assign a None Type object in the example below.
Checking the None type
Just to recap, Null is a synonym for 0 in other programming languages. However, it is an object in Python.
The type() method can be used to determine the type of None.
print(type(None))
It demonstrates that the object is None, and its data type is NoneType. In addition, None among others are built into the language. Lets, demonstrate this with the following example.
new_object = None print(type(new_object ))
As you can see, we’ve declared new_object and given it the NoneType value. When we print the result, the class NoneType is returned.
Facts to Ponder About
- False and None are not the same thing.
- None is not the same as zero.
- None is not the same thing as an empty string.
- Except for None, comparing None to anything will always result in False.
The concept of Python Null
When there is no return statement in a function, the result returned is None:
def has_no_return(): pass has_no_return() print(has_no_return())
There is no output for you to observe when you call has_no_return(). However, when you print a call to it, you’ll notice the hidden None it returns.
In fact, None happens as a return value so frequently that the Python REPL won’t report it unless you tell it to. For example,
None print(None)
None has no output on its own, but printing it to the console displays None. Print(), interestingly, provides no return value. You’ll get None as a result on the off chance that you attempt to print a call to print().
It may appear unusual, but print(print(“…”)) displays the None returned by the inner_print() as follows
print(print("codeunderscored!"))
None is also frequently used to indicate missing or default options. None, for example, appears in the list.sort documentation as shown below.
help(list.sort)
The type for the return result is None, which is also the default value for the key parameter. The precise output of help varies by platform. Running this command in your interpreter may get you a different result, but it will be similar.
Using the Null Object None in Python
When making a comparison, you’ll frequently utilize None. When you need to verify if a result or argument is None, for instance. Take the re.match result as an example. Is it possible that your regular expression matched a string? You’ll get one of two outcomes:
Return a Match object as follows: There was a match for your regular expression.
To get a None object, do the following: There was no match for your regular phrase.
You’re checking if the pattern “codeunderscored” matches a string in the code block below:
import re match = re.match(r"codeunderscored", "Hello, World!") if match is None: print("It doesn't match.")
To see if the pattern matches the string “codeunderscored,” you use is None. This code snippet illustrates a vital guideline to remember while checking for None.
Use the is and is not identity operators
The difference between the == and is operators in Python is that the == operator compares both operands’ values and verifies for equality. The is operator, on the other hand, demonstrates whether both operands relate to the same object.
The equality operators == and!= should not be used. It is because when comparing user-defined objects that override the equality operators, they can be deceived.
Example 1:
six = None print(six is None)
Example 2:
def test_python_none(): pass my_data = test_python_none() print(my_data == None) print(my_data is None)
It returns None in this code, and we verify that data is None in both ways.
When comparing user-defined objects that override the equality operators, however, they can be deceived.
class customIsAndEquivalent: def __eq__(self, other): return True my_result = customIsAndEquivalent() print(my_result == None) print(my_result is None)
In this example, the equality operator == gives the wrong result.
Because it can’t be deceived and can’t be overridden, the identity “is operator” delivers the correct response.
Example 3:
# is_comparison.py var1 = None var2 = 'codeunderscored' if var1 is None: print('var1 is None') else: print('var1 is not None') if var2 is None: print('var2 is None') else: print('var2 is not None')
class BrokenComparison: def __eq__(self, other): return True broken_c = BrokenComparison() broken_c == None # Equality operator broken_c is None # Identity operator
The equality operator == returns the incorrect result in this case. On the other hand, the identity operator cannot be deceived because it cannot be overridden.
None is false, implying that not none is correct. If all you want to verify if the result is false, a simple test like this will suffice:
some_result = None if some_result: print("Got a result!") else: print("No result.")
The output merely indicates that some result is false, not that it is exactly None. Use is and is not to determine whether or not you have a None object.
All of the following items are also false:
- Empty lists
- Empty dictionaries
- Empty sets
- Empty strings
- 0
- False
Using Python to Declare Null Variables
Variables are created by declaring them in some languages. They do not require an initial value to be assigned to them. Some sorts of variables in such languages may have null as their default value. Variables, on the other hand, assignment statements, on the other hand, bring variables to life in Python. Let’s consider the code block below.
print(bar) bar = None print(bar)
You can see how a variable with the value None differs from an undefined variable in this example. In Python, all variables are created using the assignment. In Python, you can only make a variable null by assigning None to it.
How to use None as a Default Parameter
For an optional parameter, you’ll almost always use None as the default value. There’s a valid reason to use None instead of a changeable type like a list here. Consider the following function:
def kaput_function(new_elem, starter_list=[]): starter_list.append(new_elem) return starter_list kaput_function('good')
A terrible surprise awaits you in kaput_function(). Calling the latter with an existing list works perfectly, as shown.
new_list = [‘w’, ‘x’, ‘y’]
kaput_function(‘d’, new_list )
You may easily add ‘d’ to the end of the list here.
However, if you execute this function a few times without the starter list parameter, you’ll notice that it behaves incorrectly:
kaput_function('g') kaput_function('k') kaput_function('m')
Because the default value for starter_list is only evaluated once the function is defined, the code reuses it if you don’t give an existing list.
The correct approach to construct this function is to use None as the default value, then test for it and create a new list if necessary:
def working_function(new_elem, starter_list=None): if starter_list is None: starter_list = [] starter_list.append(new_elem) return starter_list new_list = ['x', 'w', 'r', 'y', 'z'] working_function('e', new_list)
working_function ('a') working_function ('b') working_function ('c')
When you don’t present an existing list to working_function(), it operates as you expect by creating a new list with each call. It works because every time your code calls the function with the default parameter, lines 2 and 3 are executed.
How to use None in Python as a Null Value
What to do when None is a valid input object in Python What if good_function() could either add or remove an entry from the list, and None was a legitimate addition? In this instance, you can create a class that is distinct from None and is used as a default:
class classAppend: pass def working_function(new_elem=classAppend, starter_list=None): if starter_list is None: starter_list = [] if new_elem is not classAppend: starter_list.append(new_elem) return starter_list new_list= ['r', 'x', 'w', 'y', 'z'] working_function (starter_list=new_list) working_function (None, new_list)
You don’t require None because the class classAppend acts as the signal not to append. You can now add None whenever you wish.
When None is an option for return values, you can also utilize this technique. If the dictionary lacks the given key, dict.get returns None by default. If None was an acceptable value in your dictionary, you might use the following syntax to call dict.get:
class KeyNotFound: pass new_dict = {'a':15, 'd':None} for key in ['a', 'd', 'c']: value = new_dict.get(key, KeyNotFound) if value is not KeyNotFound: print(f"{key}->{value}")
You’ve created a custom class called KeyNotFound. When a key isn’t found in the dictionary, you can now return KeyNotFound instead of None. It allows you to return None when the dictionary’s actual value is None.
Tracebacks: Deciphering None
When NoneType shows in your traceback, it signifies that something you didn’t expect to be None turned out to be None, and you attempted to utilize it in a way that you couldn’t. It’s almost always because you’re trying to invoke a method on it.
For example, you called append() on my_list several times above, but append() would fail if my_list became anything other than a list:
my_list =['a', 'b', 'c', 'd', 'e', None] my_list.append('f') my_list my_list = None my_list.append('g')
Because the underlying object, my_list, is no longer a list, your code generates the very frequent AttributeError. The code throws an exception because you set it to None, which doesn’t know how to append().
Look for the attribute that caused the problem first when encountering a traceback like this in your code. It’s append() in this case. From there, you can see the object you made attempts to call it on. As you can see from the code above the traceback, it’s my_list in this case. Finally, determine how that object becomes None and take the appropriate actions to correct your code.
Check for null in Python
In Python, there are two type checking instances where null is important. When you return None, the first case is:
def returns_None() -> None: pass
It is analogous to when there is no return statement, in which case None is returned by default.
The second approach is more involving than the first. It’s used when taking or returning a value that could be None or another (single) type. This example is similar to what you accomplished earlier with re.match, which produced a Match object or None.
For parameters, the procedure is similar:
from typing import List, Optional, Any def working_function(new_elem:Any, starter_list:Optional[List]=None) -> List: pass
Make changes to working_funtion(), subsequently import Optional from typing that will result in returning an Optional[match]
Getting a Glimpse of What’s Under the Hood
Null is only a synonym for 0 in many other languages, but it is a full-fledged object in Python:
type(None)
None is an object in Python. In addition, it’s of the type NoneType, as shown in the output shown above.
None is a built-in feature of Python, just as the null:
dir(__builtins__)
None appears in the list of builtins, the builtins module’s dictionary kept by the interpreter.
None, like True and False, is a keyword. However, unlike ArithmeticError, you can’t reach None directly from builtins because of this. However, using a getattr() technique, you can get it:
__builtins__.ArithmeticError __builtins__.None print(getattr(__builtins__, 'None'))
You can retrieve the real None from builtins when you use getattr(), which you can’t do if you ask for it with builtins. None.
NoneType is not an identifier in Python, even though it appears in many error messages. It isn’t in the built-ins. You can only get there by typing (None).
You will always get the same single instance of None from the NoneType class because None is a singleton. In your Python program, there is only one None:
new_None = type(None) () # Creation of a new instance print(new_None) new_None is None
You get the existing None even if you try to create a new instance. Using id(), you can establish that None and new_None are the same objects:
id(None) id(new_None)
Because id() returns the same integer value for both None and new_None in this case, they are the same object.
Note that the value generated by id varies between computers and even between program executions. id() in CPython, the most popular Python runtime, fulfills its duty by returning an object’s memory location. The same object is two objects that have the exact memory location.
You’ll get a SyntaxError: None if you try to assign to None.
None = 20 None.age = 14 class DefClass: def assign_fnc(self): self.None = 'first val'
You can’t change None or NoneType in any of the instances above. It’s a set of true constants. As a result, it’s reasonable to presume that all None(Null) references are identical. There is no such thing as “custom.” None.
You can’t even subclass NoneType. For example,
class NewNoneType(type(None)): pass
The interpreter won’t let you create a new class that inherits from type, as seen in this traceback.
When should I utilize Python’s NoneType Object?
Use of the null or none keyword with an if statement is standard practice in almost all computer languages. However, the null keyword is not supported in Python. Instead, we can express no value with the None data type, an object type in Python.
Python null or None explanation:
- If a function returns null or None, it is considered null or None in Python.
- When the key in the collection isn’t available, it returns NoneType.
- In Python, we utilize the NoneType object to check a function’s returned value.
Conclusion
In the Python toolbox, none is a strong tool. None, like True and False, is an unchangeable keyword. In Python, the null is used to indicate missing values and results and default arguments, where it is a far better choice than changeable types.
The article also covered several methods for determining whether or not a variable contains a None value. When employing the equals to the operator or the comparison operator, make sure there are no syntax problems. But as indicated in the article, it is always safe to use is and is not for this comparison other than using the equivalent operators.
We have also noted that None can assist us in locating the specific problem in tracebacks, and we can fix it by resolving the Null issue.
You can now:
- use is and is not to test for None.
- Use None as a suitable value in your code
- Use None as a default and its equivalents.
- In your tracebacks, look for None and NoneType.
- In type hints, use None and Optional.