Python keywords are the reserved words that form the core grammar of the Python programming language. Each keyword has a specific meaning and purpose, and you cannot use any of them as variable names or identifiers in your code.
Python currently has 35 keywords, and they cover everything from controlling program flow (if, else, for, while) to defining functions (def, lambda), handling errors (try, except, raise), and managing asynchronous operations (async, await). When the Python interpreter reads your code, it matches each word against this reserved set before deciding what the code means.
That is why understanding keywords is not optional if you want to write Python that actually works.
Here is the thing that trips up a lot of developers: True and False look like keywords, but technically they are not. They are boolean literals built into Python.
The is and is not operators check object identity, while == checks for equality. The in operator checks membership in sequences like lists and dictionaries.
These operators are part of the keyword ecosystem even if they do not appear in every Python keyword list you find online. You will encounter all of them constantly, so it pays to understand how they fit into the broader picture of Python reserved words.
- Python has 35 reserved keywords that cannot be used as variable names
- True and False are boolean literals, not strict keywords, but they behave like reserved words
- The is, in, and not operators perform identity, membership, and logical checks
- async and await pair together for writing asynchronous code in Python
- Understanding keywords helps you avoid NameError and SyntaxError in real projects
What Are Python Keywords and Why Should You Care?
Python keywords are the building blocks of every Python program you will ever write. They are words that the Python interpreter reserves for its own use.
You cannot redefine them or use them as identifiers. The moment Python parses your code, it checks each token against its list of known keywords to understand what you are trying to do.
If you try to name a variable if, Python will refuse to run your code with a clear error message telling you exactly what went wrong.
Let me walk you through each keyword and what it does. This is not just academic knowledge.
I have seen developers waste hours chasing bugs that turned out to be simple keyword misuse. Knowing the full landscape of Python keywords will make you faster at reading other people’s code and more confident writing your own.
You will also understand why certain error messages appear and how to fix them quickly.
Logical and Comparison Keywords
These keywords handle boolean logic and comparisons. They evaluate conditions and return True or False.
and returns True only when both operands are True. or returns True when at least one operand is True. not inverts the truth value of whatever follows it. These three cover the basic boolean algebra you need in conditional statements.
x = True
y = False
print(x and y) # False
print(x or y) # True
print(not x) # False
The is keyword checks whether two objects are the same object in memory, not just equal in value. The in keyword checks whether a value exists inside a collection like a list, tuple, set, or dictionary.
Both is and in read naturally in English, which is part of what makes Python code readable.
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # False - different objects
print(a == b) # True - same values
print(2 in a) # True
print(5 in a) # False
One common mistake is mixing up is and ==. Use == when you care about values being equal.
Use is when you care about whether two variables point to the exact same object in memory. This distinction matters especially when you work with mutable objects like lists.
If you want a deeper dive into how Python handles equality versus identity, check out my guide on Python identifiers and best practices.
Conditional and Loop Keywords
These keywords control the flow of your program. They decide which blocks of code run and how many times.
if starts a conditional block. else provides an alternative block when the if condition is False. elif chains additional conditions when you need more than two branches. Python evaluates each condition top to bottom until one is True, then executes that block and skips the rest.
For more on how if, else, and elif work together, see my article on Python if else elif statements.
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
print(grade) # B
for iterates over a sequence like a list, string, range, or any iterable. while loops as long as a condition remains True. Both loops support break to exit early and continue to skip to the next iteration.
Python loops are expressive and readable compared to traditional index-based iteration. To master loops, read my guide on Python loops in Python.
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
if fruit == "banana":
break
print(fruit)
# Output: apple
The pass keyword is a placeholder. It does nothing but occupy space.
You need it when Python requires a statement but you have nothing to write yet. A common use case is defining an empty function or class that you plan to fill in later.
def placeholder_function():
pass # TODO: implement later
class EmptyClass:
pass
Function and Class Definition Keywords
def defines a function. You give it a name, optional parameters in parentheses, and a body indented underneath.
Functions are the primary way you organize and reuse code in Python. The return keyword sends a value back to the caller.
If you omit return or use it without a value, the function returns None. For a complete look at return behavior, see my article on the Python return statement.
def greet(name):
return f"Hello, {name}"
message = greet("Alice")
print(message) # Hello, Alice
lambda creates an anonymous function on a single line. It is useful when you need a small throwaway function, often as an argument to higher-order functions like map and filter.
Lambda functions are limited to a single expression, but they are powerful in the right context. I cover this in detail in my guide on Python lambda anonymous functions.
square = lambda x: x * x
print(square(5)) # 25
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # [2, 4, 6, 8, 10]
class defines a new object type. You use it to bundle data and behavior together.
Classes are the foundation of object-oriented programming in Python. A class can inherit from another class using the yield keyword inside a function to create a generator.
Generators produce values lazily, one at a time, which makes them memory-efficient for large sequences.
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
return f"{self.name} says woof!"
my_dog = Dog("Rex")
print(my_dog.bark()) # Rex says woof!
def count_up_to(n):
count = 1
while count
Exception Handling Keywords
Errors happen. Python gives you a structured way to handle them with try, except, finally, and raise.
The try block contains code that might throw an error. The except block catches and handles specific exceptions.
The finally block runs regardless of whether an exception occurred, making it ideal for cleanup tasks. The raise keyword throws an exception manually.
def divide(a, b):
try:
result = a / b
except ZeroDivisionError:
return "Cannot divide by zero"
except TypeError:
return "Unsupported operand types"
finally:
print("Division attempt completed")
return result
print(divide(10, 2)) # 5.0
print(divide(10, 0)) # Cannot divide by zero
The assert keyword tests a condition and raises an AssertionError if the condition is False. Think of it as a sanity check.
You use it during development to catch things that should never happen. In production, you can disable assertions with the -O flag.
For more on validating variables and function inputs, see my article on using assert for Python variable validation.
def login(username, password):
assert username != "", "Username cannot be empty"
assert password != "", "Password cannot be empty"
# login logic here
# login("", "secret") raises AssertionError: Username cannot be empty
Import and Module Keywords
Python code lives in modules and packages. You bring other modules into your code with import and from.
The as keyword gives a module or attribute an alias, which is useful when a module name is long or conflicts with a variable you already have.
import os
from pathlib import Path as FILE_PATH
from collections import defaultdict, OrderedDict
Python indentation is what defines code blocks, not curly braces like in C or Java. Indentation must be consistent throughout a file.
Mixing tabs and spaces is a classic source of bugs in Python. If you are new to Python or switching from another language, read my guide on Python indentation before you write another line of code.
Variable Scope and Management Keywords
global lets you modify a global variable from inside a function. nonlocal lets you modify a variable in an enclosing (non-global) scope. Both keywords exist because Python normally treats variables inside functions as local by default.
Without these keywords, assigning to a variable inside a function creates a new local variable rather than updating the one outside.
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1
def outer():
x = "outer"
def inner():
nonlocal x
x = "modified by inner"
inner()
print(x)
outer() # modified by inner
The del keyword removes a variable or an item from a collection. It unbinds the name from the object.
If no other references to that object exist, Python's garbage collector eventually reclaims the memory.
data = {"name": "Alice", "age": 30}
del data["age"]
print(data) # {'name': 'Alice'}
x = 10
del x
# print(x) would raise NameError
Context Manager and Asynchronous Keywords
with sets up a context manager. It guarantees that setup and teardown code runs even if an error occurs inside the block.
The most common example is working with files. Instead of manually calling file.close(), you let the context manager handle it.
This pattern is cleaner and less error-prone than try-finally blocks.
with open("example.txt", "w") as f:
f.write("Hello, world!")
# File is automatically closed here, even if an error occurs
async and await pair together for asynchronous programming. async marks a function as asynchronous, meaning it can pause and resume without blocking the entire program. await pauses an async function until a given coroutine completes. These keywords are essential for writing concurrent code that handles I/O-bound tasks efficiently, like web scraping, API calls, or database queries.
import asyncio
async def fetch_data():
await asyncio.sleep(1)
return "Data fetched"
async def main():
result = await fetch_data()
print(result)
asyncio.run(main())
# Output: Data fetched (after ~1 second)
How to List All Python Keywords in Your Version
Python ships with a module called keyword that lets you list every reserved word in your current version. This is handy when you want to verify what is available and avoid guessing.
import keyword
print(keyword.kwlist)
print(f"Total keywords: {len(keyword.kwlist)}")
Running this in Python 3.12 or later gives you the full list. The number has changed over time as Python evolved.
Python 3.10 added match and case for structural pattern matching. Python 3.11 made some soft keyword changes for typed definitions.
Running the code above on your own machine tells you exactly what your version supports.
You can also use keyword.iskeyword to check whether any string is a reserved keyword.
import keyword
print(keyword.iskeyword("if")) # True
print(keyword.iskeyword("my_var")) # False
print(keyword.iskeyword("True")) # False (True is a literal, not a keyword)
Notice that True and False return False here. That confirms they are not technically keywords.
They are built-in boolean literals. This distinction matters when you are writing tools that need to identify reserved names.
The keyword module only tracks strict keywords, not built-in literals.
How Do I Check If a Word Is a Keyword?
Beyond the keyword module, Python gives you a few ways to inspect identifiers at runtime. The most direct is calling keyword.iskeyword() on any string.
You can also check built-in names using the builtins module.
import keyword
import builtins
def is_safe_identifier(name):
if keyword.iskeyword(name):
return False, "It is a Python keyword"
if not name.isidentifier():
return False, "It is not a valid identifier"
return True, "Safe to use as a variable name"
print(is_safe_identifier("count")) # (True, ...)
print(is_safe_identifier("class")) # (False, "It is a Python keyword")
print(is_safe_identifier("my-var")) # (False, "It is not a valid identifier")
Python identifier rules are simple. A valid identifier starts with a letter or underscore, followed by any number of letters, digits, or underscores.
Unicode characters are allowed in Python 3, which means you can technically use non-Latin characters as variable names, though this is rarely done in practice.
If you are building a linter, parser, or code analysis tool, you will need to distinguish between keywords, built-ins, and user-defined names. The combination of keyword.iskeyword() and str.isidentifier() covers the core cases you need to handle.
When Should You Never Use a Keyword as a Variable Name?
The short answer is never. A keyword should never be a variable name because Python will raise a SyntaxError the moment it parses your code.
This is not a runtime error that you can catch with try-except. The parser itself rejects your code before it runs a single line.
# This will NOT run - SyntaxError
for = 42
Here is the full list of Python keywords you must avoid as variable names. Memorizing them takes time, but once you know them, you will spot potential conflicts quickly.
True, False, and None are special cases. They are not strict keywords, but shadowing them is a terrible idea.
True and False are the boolean values you rely on in every conditional. None represents the absence of a value and appears as the default return for functions that do not return anything explicitly.
If you reassign any of these names, you lose access to their built-in meaning throughout the scope where you shadowed them.
A practical rule I follow: before naming any variable, run it through keyword.iskeyword(). If it returns True, pick a different name.
Good variable names like user_count, max_value, or is_active clearly communicate intent and avoid every reserved word in Python.
Common Mistakes Developers Make with Python Keywords
After years of reviewing code and mentoring developers, I have seen the same keyword mistakes surface over and over. Let me walk through the most common ones so you can avoid them.
The first mistake is using a keyword as a variable name. Python catches this with a SyntaxError, but beginners sometimes do not understand why their code fails.
The fix is simple: rename the variable.
The second mistake is confusing is with ==. This comes up constantly when people compare strings or numbers.
Two strings that look identical might be different objects in memory. Using is instead of == for value comparison returns unexpected False results in many cases.
# Common mistake
s1 = "hello"
s2 = "hello"
print(s1 is s2) # Usually True due to string interning, but unreliable
# Correct approach
print(s1 == s2) # True
The third mistake is forgetting that variables inside functions are local by default. Trying to modify a global variable from inside a function without declaring global first creates a new local variable instead of updating the global one.
count = 0
def increment():
# count += 1 would raise UnboundLocalError without the line below
global count
count += 1
increment()
print(count) # 1
The fourth mistake is mixing up break and continue inside loops. break exits the loop entirely. continue skips the rest of the current iteration and moves to the next one. Using the wrong one leads to logic errors that can be subtle and hard to track down.
The fifth mistake is using mutable default arguments in function definitions. This one is not strictly a keyword issue, but it uses the def keyword and trips up almost every Python developer at some point.
The default list argument is created once when the function is defined, not each time the function is called.
# Common bug - default list is shared across calls
def add_item(item, items=[]):
items.append(item)
return items
print(add_item("a")) # ['a']
print(add_item("b")) # ['a', 'b'] - not what you expected
# Correct approach - use None as default
def add_item_fixed(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item_fixed("a")) # ['a']
print(add_item_fixed("b")) # ['b']
The sixth mistake is misusing try-except blocks. Catching Exception or bare except clauses masks errors you did not intend to handle.
Always catch specific exceptions and handle them appropriately. If you do not know what exception to expect, research the documentation for the function you are calling.
The seventh mistake is forgetting to use await inside async functions. An async function without await does not actually run asynchronously.
It returns a coroutine object instead of executing. You must use asyncio.run() at the top level or await the coroutine inside another async function.
async def get_data():
return "some data"
# Wrong - this just creates a coroutine object, it does not run
coro = get_data()
print(coro) #
# Correct - run the coroutine
import asyncio
result = asyncio.run(get_data())
print(result) # some data
Python Keywords and Soft Keywords in Recent Versions
Python 3.10 introduced structural pattern matching with match and case. This was a significant addition to the keyword family.
The match statement compares a subject against a series of patterns, similar to switch statements in other languages but far more powerful.
def http_status(status):
match status:
case 200:
return "OK"
case 404:
return "Not Found"
case 500:
return "Internal Server Error"
case _:
return "Unknown status"
print(http_status(200)) # OK
print(http_status(404)) # Not Found
Python 3.11 introduced the type keyword for type alias definitions and the match statement patterns refined several soft keywords. Soft keywords look like keywords in specific syntactic contexts but are valid identifiers elsewhere.
This allows libraries like dataclasses to use names that would otherwise be reserved.
Staying current with Python versions matters because the keyword set grows over time. Writing code that targets an older Python version while using newer keywords causes immediate syntax errors.
Always verify which Python version your project requires before using newer keywords like match, case, or type.
Frequently Asked Questions
How many Python keywords are there?
Python has 35 reserved keywords as of recent versions. This number has grown over time with new releases adding keywords like match and case in Python 3.10.
Is True a keyword in Python?
True and False are technically boolean literals, not strict keywords. They appear in the keyword module as soft keywords. They are reserved in the sense that you cannot use them as variable names, but they differ from true reserved keywords in subtle ways.
How do I check if a word is a Python keyword?
Use the keyword module. Import it and call keyword.iskeyword("your_word"). It returns True if the string is a reserved keyword and False otherwise.
Can I use a Python keyword as a variable name?
No. Python raises a SyntaxError if you try to use any reserved keyword as an identifier. This happens at parse time, before any code runs.
What is the difference between is and == in Python?
is checks object identity, meaning whether two variables point to the same object in memory. == checks value equality, meaning whether the values are equivalent. Use == for comparing values and is for comparing identities.
What are async and await in Python?
async marks a function as asynchronous. await pauses an async function until a coroutine completes. Together they enable concurrent code that handles I/O-bound tasks efficiently without blocking.
