Question
How do you declare a constant in Python? In Java, a constant can be declared like this:
public static final String CONST_NAME = "Name";
What is the Python equivalent, and can Python prevent the value from being changed?
Short Answer
You will learn how Python represents constants, why Python does not have Java-style enforced final variables, and how uppercase names, modules, and type hints communicate that a value should not change.
Concept
Python does not have a built-in keyword equivalent to Java's final for ordinary variables. Instead, Python uses a naming convention: write a constant's name in uppercase.
CONST_NAME = "Name"
By convention, other developers should treat CONST_NAME as read-only. However, Python does not stop code from assigning a new value later:
CONST_NAME = "Name"
CONST_NAME = "Other name" # Allowed by Python, but violates the convention
This is a deliberate aspect of Python's design. Python emphasizes clear conventions and developer responsibility rather than enforcing every rule at runtime.
Constants matter because they give meaningful names to values used repeatedly, such as API URLs, time limits, status codes, application settings, and conversion factors. A named constant makes code easier to read and safer to update than repeating a raw value in many places.
Mental Model
Think of a Python constant as a clearly labeled box with a sign that says “Do not change.”
Python lets someone open the box and replace its contents, but the uppercase label tells every programmer that doing so is against the codebase's rules.
MAX_RETRIES = 3
The uppercase name is the sign. It communicates intent: this value is a fixed rule or configuration value, not ordinary changing state.
Syntax and Examples
Use an uppercase variable name for a module-level constant:
PI = 3.14159
MAX_LOGIN_ATTEMPTS = 5
API_BASE_URL = "https://api.example.com"
Use the value like any other variable:
MAX_LOGIN_ATTEMPTS = 5
for attempt in range(MAX_LOGIN_ATTEMPTS):
print(f"Attempt {attempt + 1}")
For a stronger declaration that static type checkers can understand, use typing.Final:
from typing import Final
MAX_LOGIN_ATTEMPTS: Final = 5
Final documents that the name should not be reassigned. Tools such as Pyright and mypy can report a warning or error if you reassign it, but Python itself still permits reassignment at runtime.
from typing import Final
MAX_LOGIN_ATTEMPTS: Final = 5
MAX_LOGIN_ATTEMPTS = 10 # A type checker can flag this
Step by Step Execution
Consider this example:
TAX_RATE = 0.08
price = 50
final_price = price * (1 + TAX_RATE)
print(final_price)
Execution proceeds as follows:
TAX_RATEis bound to the float value0.08.priceis bound to50.- Python evaluates
1 + TAX_RATE, producing1.08. - Python multiplies
50 * 1.08, producing54.0. final_pricereceives54.0.print()displays54.0.
The name TAX_RATE is treated as a constant because it is uppercase and represents a value that should remain stable for the calculation.
Real World Use Cases
Constants are useful whenever a value represents a stable rule, limit, identifier, or shared setting.
-
Application configuration:
DATABASE_TIMEOUT_SECONDS = 30 -
HTTP and API settings:
API_VERSION = "v1" DEFAULT_PAGE_SIZE = 20 -
Validation limits:
MIN_PASSWORD_LENGTH = 12 -
Business rules:
FREE_SHIPPING_THRESHOLD = 50.00 -
Math and conversions:
SECONDS_PER_HOUR = 60 * 60 -
Status values:
STATUS_ACTIVE = "active" STATUS_DISABLED = "disabled"
Real Codebase Usage
In real Python projects, constants are usually defined near the top of a module or collected in a dedicated module such as constants.py.
# constants.py
DEFAULT_PAGE_SIZE = 20
MAX_PAGE_SIZE = 100
REQUEST_TIMEOUT_SECONDS = 10
Other modules import them:
from constants import DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE
def get_page_size(requested_size: int | None) -> int:
if requested_size is None:
return DEFAULT_PAGE_SIZE
if requested_size > MAX_PAGE_SIZE:
return MAX_PAGE_SIZE
return requested_size
This uses guard clauses and named constants. The function reads like a rule rather than a collection of unexplained numbers.
For groups of related fixed choices, developers often use an Enum instead of separate string constants:
from enum import Enum
class UserRole(, Enum):
ADMIN =
MEMBER =
GUEST =
Common Mistakes
Expecting Python to enforce immutability
This code is valid Python:
MAX_RETRIES = 3
MAX_RETRIES = 5
Uppercase naming is a convention, not runtime protection. Avoid reassigning uppercase names after their initial definition.
Using lowercase names for constants
max_retries = 3
This looks like a normal variable that may change. Prefer:
MAX_RETRIES = 3
Confusing an immutable value with an immutable name
A tuple cannot be modified in place, but its variable name can still be reassigned:
ALLOWED_EXTENSIONS = (".jpg", ".png")
ALLOWED_EXTENSIONS = (".gif",) # Reassignment is allowed
Likewise, an uppercase list can still be mutated:
ALLOWED_ROLES = ["admin", "member"]
ALLOWED_ROLES.append("guest") # The list changes
If a collection should not be modified, prefer immutable types such as tuples or frozenset:
Comparisons
| Feature | Python uppercase constant | typing.Final | Java static final |
|---|---|---|---|
| Example | MAX_SIZE = 100 | MAX_SIZE: Final = 100 | public static final int MAX_SIZE = 100; |
| Prevents reassignment at runtime | No | No | Yes, for the field reference |
| Communicates intent to readers | Yes | Yes | Yes |
| Checked by static analysis | Convention only | Yes, with a type checker | Yes, by the Java compiler |
| Typical use | Most Python constants |
Cheat Sheet
# Standard Python constant: uppercase by convention
MAX_RETRIES = 3
API_URL = "https://api.example.com"
# Optional type-checker support
from typing import Final
TIMEOUT_SECONDS: Final = 10
# Immutable constant collections
SUPPORTED_FORMATS = ("json", "csv")
ALLOWED_ROLES = frozenset({"admin", "member"})
- Python has no Java-style
finalkeyword for variables. - Use
UPPER_SNAKE_CASEfor constants. - Define shared constants at module level.
- Do not reassign an uppercase name after defining it.
Finalhelps static type checkers, not the Python runtime.- Uppercase does not make mutable objects like lists or dictionaries immutable.
- Use an
Enumfor a closed set of named choices.
FAQ
Does Python have constants?
Python has constants by convention. Use an uppercase name, such as MAX_RETRIES = 3, to indicate that code should not change the value.
What is the Python equivalent of Java public static final?
A module-level uppercase name is the usual equivalent:
CONST_NAME = "Name"
Optionally annotate it with Final for static type checking.
Can I make a Python variable truly constant?
Not in the same direct way as Java's final field. You can use conventions, typing.Final, immutable values, and encapsulation, but ordinary Python names can be rebound at runtime.
Should Python constants use uppercase letters?
Yes. The standard convention is UPPER_SNAKE_CASE, for example DEFAULT_TIMEOUT_SECONDS.
Does Final stop reassignment in Python?
No. Final is checked by external type-checking tools. Python itself does not enforce it when the program runs.
Where should constants go in a Python project?
Put constants near the top of the module that owns them. Put values shared across multiple modules in a dedicated module such as .
Mini Project
Description
Create a small order-validation module that uses named constants for business rules. It demonstrates how constants remove magic numbers and make validation logic easier to read and update.
Goal
Build a function that validates an order total and returns a clear result based on fixed checkout rules.
Requirements
Define constants for the minimum order amount, free-shipping threshold, and standard shipping cost. Write a function that accepts an order total as a number. Reject totals below the minimum order amount. Apply free shipping when the order reaches the threshold. Return the final total including shipping when applicable.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Add Rows to a Pandas DataFrame in Python
Learn how to add rows to a Pandas DataFrame, why repeated row appends are slow, and when to use loc, concat, or record lists.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.