I have seen this small Python choice cause surprisingly confusing bugs in automation scripts. A report-processing script reads an optional value, a function returns no result, or an API response lacks a field. You need to check for None, and both is None and == None appear to work.
They do not mean the same thing, though. One checks whether two references point to the same object, while the other asks an object to compare itself for equality.
This comparison guide explains why is None is the preferred Python pattern, where == None can fail, and how to use each operator confidently in real code.
Quick Answer: Use is None
When you need to check whether a variable has the Python None value, use:
if value is None:
print("No value was provided")
Avoid this:
if value == None:
print("No value was provided")
Both expressions often return True for a normal None value. However, is None checks identity, while == None performs an equality comparison that custom objects can change.
For that reason, Python developers use is None and is not None as the standard approach in scripts, web applications, data pipelines, and command-line tools.
If you are still getting comfortable with how Python stores and names values, start with this guide on Python variables.
is None vs == None in Python at a Glance
| Check | What it tests | Recommended for None? | Can custom code affect it? |
|---|---|---|---|
value is None | Whether value refers to the single None object | Yes | No |
value == None | Whether value compares equal to None | No | Yes |
value is not None | Whether value does not refer to None | Yes | No |
value != None | Whether value does not compare equal to None | No | Yes |
The key point is simple: None is a singleton. A singleton is an object that Python creates only once. Every None reference in your program points to that same object.
That makes an identity check both clear and reliable:
report_name = None
print(report_name is None)
Output:
True
I executed the above example code and added the screenshot below.

The code does not compare text, numbers, or object contents. It directly asks whether report_name refers to Python’s one None object.
What is None Means in Python
The is operator checks object identity. Identity means whether two variables point to the same object in memory.
Here is a small example:
missing_file = None
result = missing_file is None
print(result)
Output:
True
This check works well when a function uses None to signal “no result,” “not configured,” or “not found.”
For example, imagine a local reporting script that looks for an optional configuration value:
def get_report_folder(settings):
return settings.get("report_folder")
settings = {"email_enabled": True}
report_folder = get_report_folder(settings)
if report_folder is None:
print("Using the default report folder")
else:
print(f"Saving files to: {report_folder}")
The dictionary .get() method returns None when the requested key does not exist and you do not provide a fallback value. The is None check makes that intent obvious to anyone maintaining the script.
You can also reverse the condition:
if report_folder is not None:
print(f"Custom folder selected: {report_folder}")
Use is not None when you only need to confirm that a value exists. This is especially useful before calling a method or processing an optional function result.
Pro Tip: In my experience,
is not Noneprevents many automation bugs because it does not confuse missing values with valid false-like values such as0,False, or an empty string.
What == None Means in Python
The == operator checks equality. It asks whether the value on the left should be considered equal to the value on the right.
With basic values, this looks harmless:
status = None
print(status == None)
Output:
True
I executed the above example code and added the screenshot below.

Python evaluates this as True because status really is None. But the equality operator can call a special method named __eq__ on custom objects.
A special method is a Python method with double underscores. It lets a class control built-in behavior, including equality checks.
class ReportStatus:
def __eq__(self, other):
return True
status = ReportStatus()
print(status == None)
print(status is None)
Output:
True
False
This result shows the problem clearly. The ReportStatus object is not None, but its custom __eq__ method claims it equals everything.
A check using == None could send your script down the wrong path. A check using is None still gives the correct result because it checks the object itself, not its custom comparison rules.
For a broader look at these two operators, see the difference between is and == in Python.
Why is None Is the Better Choice
It states your intent clearly
When another developer sees this code, they immediately understand that you expect a missing value:
if customer_id is None:
raise ValueError("Customer ID is required")
The expression says, “This value must not be absent.” It does not suggest that you want to compare two business values.
By contrast, this version makes readers pause:
if customer_id == None:
raise ValueError("Customer ID is required")
The code still may work, but it does not communicate the correct intent as clearly.
It avoids overloaded equality methods
Classes can define __eq__, and third-party libraries often use it for useful comparisons. That flexibility helps when comparing domain objects, but it makes == None unreliable.
For instance, a data object might compare itself to another record by ID. A library object might return a special comparison result instead of a single True or False.
Use is None whenever the question is specifically, “Did I receive no object?”
It works cleanly with optional function results
Functions often return None when they complete an action but have nothing meaningful to return.
def write_summary(lines):
with open("summary.txt", "w", encoding="utf-8") as file:
file.write("\n".join(lines))
saved_file = write_summary(["Sales report complete", "12 records processed"])
if saved_file is None:
print("The summary was written successfully")
The write_summary() function creates a local text file but has no return statement. Python therefore returns None automatically.
If you build file-based automation, you may also find this guide on how to check whether a file exists in Python useful.
Do Not Use Truthiness When You Need None
A common shortcut looks like this:
record_count = 0
if not record_count:
print("No value found")
This code prints the message, even though 0 is a valid number. Python treats 0, False, empty strings, empty lists, and empty dictionaries as false-like values.
If your script must distinguish between “missing” and “present but empty,” check for None directly:
record_count = 0
if record_count is None:
print("No value was provided")
else:
print(f"Processed {record_count} records")
Output:
Processed 0 records
I executed the above example code and added the screenshot below.

This distinction matters in data cleanup, form processing, and reporting scripts. A zero sales total does not mean the same thing as an unavailable sales total.
For related list-cleaning work, learn how to remove None values from a Python list.
A Practical Example With API-Style Data
Imagine a script that receives JSON-like dictionary data from an internal service. Some customers have a phone number, while others do not.
customer = {
"name": "Asha",
"phone": None
}
phone_number = customer.get("phone")
if phone_number is None:
print("Phone number is missing. Skip the SMS notification.")
else:
print(f"Send SMS to {phone_number}")Output:
Phone number is missing. Skip the SMS notification.
This pattern keeps the script safe. You identify a missing optional field before trying to format it, send it to another service, or write it to a file.
Do not replace the condition with if not phone_number: unless an empty string should receive the same treatment as None. That decision depends on your data rules.
When Should You Use == in Python?
Use == when you want to compare values, not identities.
expected_status = "complete"
current_status = "complete"
if current_status == expected_status:
print("The report is ready")
Here, equality is exactly what you need. The two strings may exist as separate objects, but their text content matches.
Use == for values such as:
- Strings, numbers, dates, and Boolean values
- Lists, tuples, dictionaries, and sets
- Custom objects where equality has a meaningful business definition
Use is mainly for singleton values, especially None. You may also see it with True and False, but direct Boolean checks usually read better:
is_complete = True
if is_complete:
print("Task finished")
Things to Keep in Mind
- Use is None consistently: It clearly checks for Python’s missing-value object and avoids custom equality behavior.
- Use is not None for valid zero values: This check keeps
0,False, and empty strings separate from missing data. - Do not compare empty values blindly:
None,"",[], and{}can mean different things in a real script. - Avoid == None in new code: It may work today but can produce incorrect results with custom classes or library objects.
- Handle missing dictionary keys intentionally: Use
.get()whenNoneis an acceptable fallback, or use direct indexing when a key must exist. - Watch for data-analysis null values: None and NaN are different values, so they need different checks in a pandas workflow.
Frequently Asked Questions
Is is None faster than == None in Python?
is None is generally simpler because Python only checks whether both references point to the same singleton object. The performance difference rarely matters in normal code, but is None remains the correct choice because it is reliable and clear.
Why does Python recommend is None instead of == None?
Python recommends is None because None is a singleton. The identity check cannot trigger a custom __eq__ method, while == None can produce unexpected results with custom objects.
Can I use is to compare strings or numbers?
Do not use is for normal strings or numbers. Use == because you usually want to compare values, not whether Python stored both variables as the same object.
What is the difference between None and an empty string in Python?
None means no value exists. An empty string, written as "", is still a real string value with zero characters. Use is None when you need to detect absence, and use == "" when you need to detect an empty string.
Should I use if not value instead of if value is None?
Use if not value only when None, 0, False, and empty collections should all follow the same path. Use if value is None when you must distinguish a missing value from a valid false-like value.
Does None == None return True?
Yes, None == None returns True. Still, write None is None or value is None when you specifically test for None, because identity is the intended check.
The practical difference between is None and == None comes down to identity versus equality. Use is None whenever you need to detect a missing value, and reserve == for comparing actual values. I hope you found this article helpful.
You May Also Like
- Difference between
==and=in Python - Check if a string is empty in Python
- Understand Python functions with optional arguments
- Use Python type hints for more robust code
- Check if a pandas DataFrame is empty

Bijay Kumar is an experienced Python and AI professional who enjoys helping developers learn modern technologies through practical tutorials and examples. His expertise includes Python development, Machine Learning, Artificial Intelligence, automation, and data analysis using libraries like Pandas, NumPy, TensorFlow, Matplotlib, SciPy, and Scikit-Learn. At PythonGuides.com, he shares in-depth guides designed for both beginners and experienced developers. More about us.