Naming things well is one of the hardest parts of programming, and it is also one of the most important. A name is the first clue a reader gets about what a piece of code does. A good name saves minutes of reading. A bad name forces the reader to trace through logic just to understand what a variable holds.
Python has strong naming conventions defined in PEP 8, and the community follows them consistently. This article covers which convention to use for each kind of name, what makes a name good or bad, and how to choose names that make your code self-documenting. For the full formatting rules behind these conventions, see the PEP 8 style guide.
Before naming anything in Python, understand the core rule: use snake_case for variables and functions, PascalCase for classes, and UPPER_CASE for constants.
# Variables: snake_case
user_count = 42
max_retry_attempts = 3
# Functions: snake_case
def calculate_total(items):
return sum(items)
# Classes: PascalCase
class ShoppingCart:
pass
# Constants: UPPER_CASE
DEFAULT_TIMEOUT = 30
MAX_CONNECTIONS = 100This is not a preference. It is the community standard. When you follow it, anyone who reads Python will immediately know what kind of thing each name refers to.
Naming variables: reveal what the value represents
A variable name should answer the question "what does this hold?" The reader should not need to read the code that assigns the value to understand the variable.
Names should describe intent, not type or implementation. Bad names focus on what the thing is made of, while good names focus on what the thing means:
# Bad: describes the data structure, not the meaning
str_list = ["Ada", "Grace", "Alan"]
int_dict = {"Ada": 28, "Grace": 32}The names str_list and int_dict tell you about types. But the reader still does not know what the data represents.
Good names answer the "what is this" question directly:
# Good: describes what the data represents
student_names = ["Ada", "Grace", "Alan"]
student_ages = {"Ada": 28, "Grace": 32}Avoid encoding type information in the name. Hungarian notation like strName or iCount is not idiomatic Python. Python is dynamically typed, and a variable might hold different types at different times.
Longer names suit larger scope, shorter names suit smaller scope. A loop index that lives for two lines can be a single letter. A variable that appears across a 50-line function deserves a descriptive name:
# Short scope: single-letter is fine
squares = [n ** 2 for n in numbers]
for i in range(3):
print(i)
# Long scope: descriptive name is required
invoice_total_before_tax = sum(item.price for item in cart.items)
days_since_last_login = (now - user.last_login).daysAvoid noise words. Terms like data, info, obj, thing, and manager say nothing specific:
- Instead of
user_data, writeuser. - Instead of
result_info, writereport. - Instead of
process(data_obj), writeprocess(order).
Boolean names should read as a question. Use prefixes like is_, has_, can_, and should_ so the name reads naturally in an if statement:
# Reads naturally in conditions
if is_active:
send_notification()
if has_permission:
grant_access()
if can_edit:
show_editor()Each condition reads like a question you would ask in plain English. The naming convention does the work of documenting intent without a single comment.
The article on Python variables and object references covers how variable assignment works under the hood. The name is the only label you have for the object in memory, so choosing a good one matters for every line that follows.
Naming functions: start with a verb
A function does something, so its name should be a verb or a verb phrase. When a reader sees the name, they should know what action the function performs.
# Good: verb phrases
def calculate_tax(amount, rate):
return amount * rate
def send_welcome_email(user):
email_service.deliver(user.email, WELCOME_TEMPLATE)
def parse_config_file(path):
with open(path) as fh:
return toml.load(fh)Functions that return a boolean should read like a question or a predicate, so the caller can use the result directly in an if statement without translating the name in their head. The is_ and has_ prefixes below make the return type obvious before you even read the function body:
def is_valid_email(address):
return "@" in address and "." in address.split("@")[-1]
def has_expired(token):
return token.created_at + token.ttl < time.time()Private helper functions should use a leading underscore. This convention signals that the function is an implementation detail, not part of the public API:
def load_users(filepath):
"""Load users from a JSON file."""
raw = _read_file_contents(filepath)
return [_parse_user(entry) for entry in raw]
def _read_file_contents(path):
"""Internal: read and return file text."""
with open(path) as fh:
return fh.read()
def _parse_user(entry):
"""Internal: convert a raw dict into a User object."""
return User(name=entry["name"], email=entry["email"])Functions without a return value should still use a verb name. The reader knows the function does its work through a side effect. For more on writing functions that are easy to name well, see Python functions explained.
Naming classes: use a noun or noun phrase
A class represents a concept, an entity, or a thing. Its name should be a noun. Unlike functions, classes do not start with a verb because they model what something is, not what it does.
# Good: noun phrases
class ShoppingCart:
pass
class EmailMessage:
pass
class DatabaseConnection:
passAvoid suffixes like _class, _obj, or _type. The PascalCase naming already tells the reader it is a class. When a class models an exception, end the name with Error:
class ValidationError(Exception):
pass
class ConnectionTimeoutError(Exception):
passSome projects use a Base prefix for abstract base classes, like BaseImporter. For a deeper dive into class design, see the section on building reusable Python classes.
Naming modules and packages
Module names should be short, lowercase, and use underscores only if it improves readability. Good examples: models.py, email_utils.py, data_processor.py. Bad examples: Models.py (PascalCase), email-utils.py (hyphens are not valid Python identifiers).
Package names follow the same rule but are usually a single short word. Avoid naming a module the same as a standard library module like email, json, or csv. This shadows the built-in module and causes confusing import errors.
Naming constants: ALL_CAPS with underscores
Constants are values that should not change after the program starts. Use uppercase letters with underscores. Place constants at the module level near the top of the file, after imports and before function definitions:
MAX_RETRIES = 5
DEFAULT_CHUNK_SIZE = 1024
DATABASE_URL = "postgresql://localhost/myapp"
SECONDS_IN_AN_HOUR = 3600Python does not enforce constant behavior. MAX_RETRIES = 5 can still be reassigned. The uppercase convention is a promise to the reader, not a compiler rule.
Names to avoid
Some names are technically valid in Python but should never be used. Single-letter names are acceptable only in tight loops or comprehensions. Ambiguous characters like lowercase l, uppercase O, and uppercase I are easily confused with digits. Python keywords like class, def, if, and return cannot be used as names.
Built-in name shadowing is a common mistake. Avoid names like list, dict, str, sum, max, id, type, and input. Reusing these shadows the built-in and causes confusing errors:
# Dangerous: shadows the built-in list type
values = [1, 2, 3] # fine: this creates a list
# Later, if you wrote `list = [...]` earlier:
names = list("abc") # TypeError because list is now a list, not the typeDouble-underscore names (dunders) like init, str, and len are reserved for Python's special methods. Do not invent your own dunder names. The one trailing underscore exception is when you need to use a name that would otherwise shadow a built-in, like type_ or class_.
Practical naming workflow
When you create a new variable, function, or class, take five seconds to ask: if someone reads only this name, will they know what it holds or does? Does the name follow the Python convention for its kind? Is the name specific enough to be useful but short enough to be readable?
Naming is hard because it requires you to understand what the code does before you name it. If you cannot find a good name, the problem might be that the function or class is doing too many things. Split it until each piece has a clear, nameable responsibility.
Rune AI
Key Insights
- Use snake_case for variables, functions, methods, and modules; PascalCase for classes; UPPER_CASE for constants.
- Choose names that reveal intent: user_count not uc, calculate_total not ct.
- Functions should be verbs or verb phrases; classes should be nouns.
- Boolean variables should read like a question: is_active, has_permission.
- Avoid single-letter names except in short comprehensions and loop indices.
Frequently Asked Questions
What naming convention does Python use for variables?
Can I use camelCase in Python?
Conclusion
Good names are the cheapest form of documentation. A well-named variable, function, or class tells the reader what it holds, what it does, or what it represents without requiring a comment. Spend a few extra seconds on each name. The time you save in future debugging and code review will repay that investment many times over.
More in this topic
How to Test Python Code
Learn what testing means in Python, the core ideas behind automated tests, and the built-in and third-party tools that make testing practical.
Write Your First Python Unit Test
Write and run your first Python unit test step by step, using unittest to check a small function and understand the test output.
The Factory Pattern in Python
Learn how to use the factory pattern in Python to encapsulate object creation, making your code more flexible and easier to extend.