Text & WritingJuly 13, 2025·8 min read

Python Naming Conventions: The Complete PEP 8 Guide with Examples

PEP 8 naming conventions for Python variables, functions, classes, constants, and files — with before/after code examples, a linter reference, and a complete naming grid you can bookmark.

Python naming conventions and PEP 8 define exactly how variables, functions, classes, constants, and files should be named in Python code. Unlike style preferences in some languages, Python's conventions are codified in PEP 8 — the official style guide — and enforced automatically by linters like flake8, pylint, and ruff in virtually every professional Python project. Getting a camelCase variable name flagged in a code review is a common (and avoidable) experience for developers learning Python after JavaScript or Java.

Python naming conventions — the complete PEP 8 reference

Here is every Python naming convention in one place, colour-coded by convention type:

Python PEP 8 naming conventions reference gridColour-coded grid showing all Python PEP 8 naming conventions. Variables and functions use snake_case (blue). Classes use PascalCase (green). Constants use UPPER_SNAKE_CASE (amber). Private attributes use _single_underscore (purple). Dunder methods use __double_underscore__ (red). Packages use lowercase (grey).Identifier typePEP 8 conventionExamplesVariablessnake_caseuser_id, item_count, is_activeFunctionssnake_caseget_user(), calculate_total()ClassesPascalCaseUserProfile, HttpClientConstantsUPPER_SNAKE_CASEMAX_RETRIES, API_KEYModules / filessnake_casedata_processor.py, api_client.pyPrivate attributes_single_underscore_internal_value, _helper()Dunder methods__double_under____init__, __str__, __repr__Packageslowercaserequests, numpy, mypackagesnake_casePascalCaseUPPER_SNAKE_CASE_private__dunder__
PEP 8 naming conventions — enforced by flake8, pylint, and ruff in professional Python codebases

The most important takeaway: Python uses snake_case for almost everything — variables, functions, methods, module names, and file names. The only exceptions are class names (PascalCase) and constants (UPPER_SNAKE_CASE). If you remember only this, you will write PEP 8-compliant Python 95% of the time.

Python variable naming rules and examples

All Python variable names follow snake_case: all lowercase letters, with underscores separating words. Numbers are allowed but cannot start the name.

# ✅ Correct — PEP 8 snake_case
user_id = 42
first_name = "Alice"
item_count = 0
is_active = True
base_url = "https://api.example.com"
max_retry_count = 3

# ❌ Wrong — camelCase (Java/JavaScript style)
userId = 42
firstName = "Alice"
itemCount = 0
isActive = True

# ❌ Wrong — PascalCase (class style)
UserId = 42
FirstName = "Alice"

Linter warning: If you use camelCase for a variable in Python, flake8 raises N806 (variable in function should be lowercase) or pylint raises C0103 (invalid-name). These warnings fire automatically in most CI/CD pipelines.

Special cases: A single underscore _ is used as a throwaway variable name — for loop variables you do not need:

# _ means "I don't need this value"
for _ in range(10):
    do_something()

# __ is used to unpack when you only need part of a tuple
first, *_, last = [1, 2, 3, 4, 5]

Python function naming with examples

Functions follow the same snake_case rule as variables. A well-named Python function reads like an English verb phrase:

# ✅ Correct — descriptive snake_case
def get_user_by_id(user_id: int) -> User:
    ...

def calculate_monthly_payment(principal, rate, term):
    ...

def parse_json_response(response_text: str) -> dict:
    ...

def is_valid_email(email: str) -> bool:
    ...

# ❌ Wrong — camelCase (JavaScript habit)
def getUserById(userId):
    ...

def calculateMonthlyPayment(principal, rate, term):
    ...

Boolean functions conventionally start with is_, has_, or can_: is_authenticated(), has_permission(), can_retry().

Python class names — PascalCase explained

Class names are the main exception to snake_case. All Python class names use PascalCase (also called UpperCamelCase): every word starts with a capital letter, no underscores.

# ✅ Correct — PascalCase class names
class UserProfile:
    pass

class DatabaseConnection:
    pass

class HttpClientError(Exception):  # Exception subclasses too
    pass

class APIRateLimiter:  # Acronyms treated as one word (API not A_P_I)
    pass

# ❌ Wrong
class user_profile:   # snake_case for a class
    pass

class userProfile:    # camelCase for a class
    pass

Exception classes always end with Error or Exception: ValidationError, ConnectionTimeoutError, PaymentProcessingException. This is PEP 8 convention plus strong community standard — it immediately signals that the class is meant to be raised and caught.

The difference between snake_case and camelCase in Python

The most common confusion comes from developers moving between Python and JavaScript — the two most used languages, with opposite naming conventions for variables.

ConceptPython (snake_case)JavaScript (camelCase)Java (camelCase)
Variableuser_first_nameuserFirstNameuserFirstName
Functionget_total_price()getTotalPrice()getTotalPrice()
ClassUserAccountUserAccountUserAccount
ConstantMAX_SIZEMAX_SIZEMAX_SIZE
File / moduleuser_service.pyuserService.jsUserService.java

The API mismatch problem: When a Python backend (FastAPI, Django) sends JSON to a JavaScript frontend, the names collide. Python uses first_name; JavaScript expects firstName.

The clean solution is to configure serialisation to auto-convert. In Pydantic (used by FastAPI):

from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel

class UserResponse(BaseModel):
    model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

    first_name: str   # stored as snake_case in Python
    user_id: int      # serialised as firstName, userId in JSON

To convert names manually between conventions, use the Snake Case Converter and Camel Case Converter.

Constants — UPPER_SNAKE_CASE

Module-level constants use all uppercase with underscores separating words. This makes constants immediately visually distinct from variables in any code reader.

# ✅ Module-level constants — UPPER_SNAKE_CASE
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30
API_BASE_URL = "https://api.example.com"
DATABASE_URL = "postgresql://localhost:5432/mydb"

# Used in environment-variable-backed settings
import os
SECRET_KEY = os.environ.get("SECRET_KEY", "")
DEBUG = os.environ.get("DEBUG", "False") == "True"

How linters enforce PEP 8 naming automatically

You do not need to memorise every rule — linters catch violations in real time. Here are the three most-used Python linters and the naming codes they raise:

LinterCodeWhat it catches
flake8 + pep8-namingN801Class name not CapWords (PascalCase)
flake8 + pep8-namingN802Function name not lowercase
flake8 + pep8-namingN803Argument name not lowercase
pylintC0103Name doesn't conform to naming style (all types)
ruffN*All pep8-naming rules — fastest linter available

Recommended setup for a new project:

# Install ruff (fastest, includes naming rules)
pip install ruff

# Run on your project
ruff check .

# Auto-fix what can be fixed
ruff check --fix .

# Add to pre-commit hook so it runs before every commit
# .pre-commit-config.yaml:
# - repo: https://github.com/charliermarsh/ruff-pre-commit
#   hooks:
#     - id: ruff

Key takeaways

  • Use snake_case for variables, functions, methods, modules, and file names.
  • Use PascalCase for class names — the only exception to snake_case.
  • Use UPPER_SNAKE_CASE for module-level constants.
  • Use a single underscore prefix (_name) for internal/private attributes.
  • Double underscores (__name__) are reserved for Python dunder methods — do not invent your own.
  • Install ruff or flake8 with pep8-naming — the linter catches every violation automatically.
  • Use Snake Case Converter to convert existing camelCase names to PEP 8 format.

Frequently asked questions

Why does Python use snake_case instead of camelCase?

Guido van Rossum chose snake_case for Python's standard library in the early 1990s, drawing on Unix/C conventions of the time. Readability studies since then have confirmed that snake_case is slightly easier to read than camelCase for multi-word identifiers — the underscores create clear word boundaries without relying on case detection. PEP 8 formalised this choice as the official convention in 2001.

Can I use camelCase in Python if my team prefers it?

Technically yes — Python will run the code either way. But doing so means disabling or suppressing naming rules in your linter, inconsistency with the standard library and most third-party libraries, and friction for any new developer who joins the project. PEP 8 is the community standard: deviating requires a stronger reason than personal preference.

How do Python naming conventions handle acronyms?

Treat acronyms as words. In snake_case: parse_html_content (not parse_HTML_content), api_client (not API_client). In PascalCase: HttpClient (not HTTPClient), ApiGateway (not APIGateway). The exception: established abbreviations where the all-caps version is universally recognised, like JSONDecoder or URLParser — both common in Python's stdlib.

What is the difference between _name and __name in Python?

Single underscore (_name) is a convention meaning "internal use" — it is not enforced by Python but signals to other developers not to use this attribute directly. Double underscore (__name) triggers name mangling — Python renames it to _ClassName__name to avoid conflicts in subclasses. Double underscores on both sides (__name__) are "dunder" methods reserved by Python — never create your own __custom__ attributes.

Does PEP 8 apply to Jupyter notebooks?

PEP 8 applies to any Python code, including notebooks. In practice, exploratory analysis notebooks are often less strict — single-letter variable names like df for DataFrame are universally accepted. But production-grade notebooks and those shared publicly benefit from PEP 8 compliance: it makes them far easier for others to read and adapt.

Free tool

Try the Snake Case Converter

Use our free snake case converter to calculate results instantly — no signup required.

Open Snake Case Converter
Tags:pythonpep8naming conventionssnake_casecamelCaselintingcode style