Table of Contents

What Will You Learn
This tutorial introduces constants in Python, explains their role in writing clean, maintainable code, and shows how to define them using naming conventions. You'll also learn where and why to use constants in real-world projects.


Professional development is impossible without structure and predictability. When code uses fixed values — such as connection limits, API keys, mathematical constants, or default settings — they should not be written directly into the logic. Doing so is considered poor practice and risky. To ensure stability, readability, and scalability, such values are moved into constants.

This is not a syntactic feature of Python, but rather a discipline and coding style. Knowing where and how to use constants is a fundamental skill for every developer, even at the beginner level.

What is a Constant in Python?

A constant is a variable whose value is fixed within the logic of the program. Its purpose is to represent an important value that should not be accidentally or mistakenly changed. In other languages (such as Java or C++), there are keywords like final or const that strictly prohibit modifying a variable. In Python, no such mechanism exists. Everything is based on conventions and style.

Nevertheless, constants play a vital role. They allow you to extract key parameters from function bodies and business logic, define them in one place, reuse them, and change them if necessary — without having to search across dozens of files.

What are the 4 Types of Constants?

Constants can be categorized by their purpose. This is not an official classification but a practical approach commonly used in code architecture:

  • Mathematical constants — such as PI, E, GOLDEN_RATIO. Used in calculations and rarely changed.
  • Configuration valuesTIMEOUT, MAX_RETRIES, BUFFER_SIZE. Responsible for technical settings and environment parameters.
  • Formatting strings — date formats, file paths, prefixes: LOG_PATH, DATE_FORMAT, EXPORT_FILENAME_TEMPLATE.
  • Flags and modes — boolean variables like DEBUG, IS_PRODUCTION, ENABLE_CACHE that control application behavior.

Examples of commonly used constants in Python

Name Type Example Value Purpose
PI float 3.14159 Mathematical constant
MAX_USERS int 100 User limit
API_KEY str '123abcXYZ' API access key
TIMEOUT_SECONDS int 30 Request timeout duration
DEFAULT_LANGUAGE str 'en' Default interface language
BASE_URL str 'https://example.com/api' Base URL for HTTP requests
IS_PRODUCTION bool True Production environment flag (or debug)

How Should Constants be Named in Python?

Naming constants is a crucial part of their usage. Poor naming leads to confusion, bugs, and misunderstandings within the team. In Python, the UPPER_SNAKE_CASE style is used to denote constant values. This style makes it easy to distinguish a constant from a regular variable, even without context. This is especially important in large projects, where code readability and clarity directly impact team productivity.

Examples of proper naming:


    MAX_RETRIES = 5
    PI = 3.14159
    DEFAULT_TIMEOUT = 30
    IS_PRODUCTION = True
    BASE_URL = "https://api.example.com"
    DATABASE_NAME = "project_db"
    DATE_FORMAT = "%Y-%m-%d"

Each name conveys its meaning without needing additional comments. For example, BASE_URL clearly indicates that the variable holds the base address for HTTP requests, and IS_PRODUCTION is a boolean flag for the environment.

Examples of poor naming (to be avoided):


    maxRetries = 5 # wrong style (camelCase) 
    pi = 3.14 # looks like a regular variable 
    url = "https://..." # vague, too generic 
    x = True # not informative 
    defaulttimeout = 30 # unreadable, no word separation

Such code is harder to read, maintain, and understand by other developers — especially in large projects or team environments.

Rules for naming constants:

  • Use uppercase letters.
  • Separate words with underscores.
  • Avoid abbreviations unless widely accepted.
  • Use meaningful and self-explanatory names.

Following these simple rules ensures a consistent style and makes the project easier to maintain. 

How to Make Constants in Python?

Creating a constant in Python doesn’t require special syntax. Just assign a value to a variable with an uppercase name:


    PI = 3.14 
    MAX_RETRIES = 5 
    BASE_URL = "https://api.example.com"

However, it’s important to remember: this is only a convention. There is no built-in protection against modification. A constant can be overwritten, which may lead to a logical error. That’s why it’s helpful to use editors with hints and linters (like pylint) to detect such cases.

Why Use Constants?

Constants make code predictable and manageable. You explicitly state that a value should not be changed under any circumstances. This becomes a sort of contract between you and the rest of the program. Using constants isn’t about “style” — it’s about control.

In real-world projects, most bugs come not from algorithms, but from details — accidental changes to values, variable reassignments, or hardcoded numbers/strings in multiple places. Constants eliminate these risks. They allow you to extract key values from the logic, removing so-called “magic numbers” — unclear values written directly in the code, such as:

if x > 72:  # Why 72? What does it mean?

Using a constant:

if x > MAX_LOGIN_ATTEMPTS:

Now the code is clear, the logic is obvious, and the value can be changed quickly in one place — without searching the entire project.

Reasons to use constants:

  • Safety — protection from accidental changes in logic or in the editor. A constant is a signal that says: “don’t touch me.”
  • Clarity — instead of if timeout > 10: you write if timeout > DEFAULT_TIMEOUT:. The second version explains itself.
  • Centralization — constants are defined in one place, and when something changes (e.g., an API key or limit), you don’t have to edit dozens of files.
  • Scalability — in a production environment, you can override parameters without changing the logic, simply by swapping out the constants module.
  • Testability — during unit testing, you can temporarily override a value without touching the business logic.
  • Reusability — the same value (e.g., PAGE_SIZE = 20) can be reused in different functions, modules, or even projects.
  • Configurability — you can extract parameters into separate config files (.env, .json, .yaml) and load them into the constants module automatically.

As a result, using constants makes code not only correct but also understandable to the team that will read and maintain it after you.

When to Use Constants?

Working with constants is not an “optional” practice, but a cornerstone of engineering discipline. Beginners often think that constants are only needed in complex systems. But the truth is, the simpler the system, the more beneficial proper structure becomes. Constants simplify even small scripts, turning them into stable tools.

They should not be used “when necessary,” but by default — every time you work with fixed values that the program logic depends on. This is especially important in the following cases:

  • The value is repeated in multiple parts of the code. Instead of writing if score > 100:, if max(score) < 100:, use MAX_SCORE = 100.
  • The parameter may change in the future. File paths, limits, URLs, time intervals — all of these can be moved to constants and easily updated when needed.
  • The logic depends on a specific string or number. For example, 'application/json' or 5000 for a timeout. If it's a critical element, define it as CONTENT_TYPE_JSON or DEFAULT_TIMEOUT_MS.
  • The variable acts as a mode flag. Flags like DEBUG = True, IS_PRODUCTION = False allow you to quickly switch application behavior without rewriting logic.
  • There is a dependency on external APIs or files. Any external dependency is a risk zone. URLs, keys, file names — all should be centralized and defined in a separate module.
  • You need a single control point for parameters. One file with constants gives you control over the whole system and eliminates inconsistencies between modules.
  • You want documentation directly in the code. A well-named constant (DEFAULT_LANGUAGE = 'en') serves as documentation. There’s no need to explain why 'en' is used — the name makes it clear.

Using constants is the foundation of clean code. You might not notice them until they’re needed. But when they're absent, navigating the code becomes a risky game of “find and don’t break.”

How to Define Constants in Python?

It is recommended to place all constants in a separate file. Typically this is a module like constants.py, settings.py, or config.py, where all values used across the application are listed.


    # constants.py
    API_KEY = "abc123"
    DEFAULT_LANGUAGE = "en"
  

Import in other files is done like this:

from constants import API_KEY

Or, to avoid name conflicts:


    import constants
    print(constants.API_KEY)

This approach makes the project architecture flexible and manageable. If you need to change a value, you do it in one place — and it’s applied throughout the entire system.

Common Mistakes Made by Beginners and How to Fix Them

1. Using Magic Numbers and Strings in Code

Mistake:
A beginner writes hardcoded values directly into the program logic without any explanation:


    if response.status_code == 403: 
      print("Access denied")
  

Why it's bad:
It's unclear what 403 means or why it signals an access error. This reduces readability and makes maintenance harder.

How to fix it:
Extract the value into a constant with a meaningful name:


    FORBIDDEN_STATUS = 403
    if response.status_code == FORBIDDEN_STATUS:
      print("Access denied")
  

2. Reassigning a Constant

Mistake:
After initially declaring a constant-style variable, the programmer accidentally reassigns it:


    MAX_RETRIES = 3
    MAX_RETRIES = 5  # error: constant reassignment
  

Why it's bad:
This violates the principle of immutability and can make the program behave unpredictably.

How to fix it:
Enforce "read-only" variables through discipline. Use a separate module and avoid reassignment. For additional protection, consider using types.MappingProxyType or Enum.

3. Incorrect Naming Style for Constants

Mistake:
A constant is named like a regular variable:


    timeout = 10
  

Why it's bad:
This style doesn’t distinguish constants from mutable values, leading to confusion when reading the code.

How to fix it:
Stick to UPPER_SNAKE_CASE:


    TIMEOUT_SECONDS = 10
  

4. Defining Constants Inside Functions

Mistake:
Declaring a constant inside a function, which causes it to be recreated on each call:


    def connect():
      API_URL = "https://api.example.com"
  

Why it's bad:
This reduces performance and breaks the "single source of truth" principle. The constant also becomes unavailable to other modules.

How to fix it:
Move all constants to the module level:


    # config.py
    API_URL = "https://api.example.com"
  

5. No Centralized Constant Storage

Mistake:
Values are scattered across all files without logical structure.

Why it's bad:
Changes require searching the project, which easily leads to inconsistencies and duplication.

How to fix it:
Create a separate constants.py or settings.py file and import values from there:


    # constants.py
    DEFAULT_LANGUAGE = "en"
    PAGE_SIZE = 20
  

6. Storing Sensitive Data Directly in Code

Mistake:
Constants like API_KEY = "123abc" are written directly in the code and end up in the repository.

Why it's bad:
It’s a direct security risk. Keys and passwords must be protected from access.

How to fix it:
Move such values to environment variables or config files and load them via os.environ:


    import os
    API_KEY = os.environ.get("API_KEY")
  

7. Using Mutable Objects as Constants

Mistake:
A beginner creates a “constant” — a list or dictionary — and later modifies it:


    DEFAULT_HEADERS = {"Content-Type": "application/json"}
    DEFAULT_HEADERS["X-Token"] = "secret"  # modifying a "constant"
  

Why it's bad:
Although the name looks like a constant, the object remains mutable.

How to fix it:
Use immutable types: frozenset, namedtuple, or types.MappingProxyType for full protection:


    from types import MappingProxyType
    DEFAULT_HEADERS = MappingProxyType({"Content-Type": "application/json"})
  

Working with constants is not about syntax — it’s about discipline. Applying best practices from the start will save you from many errors in the future. The earlier you develop the habit of extracting fixed values into named entities, the easier it will be to maintain and scale your projects.

FAQ

What are the best practices for naming constants in Python?

All constant names should be short, precise, and written in uppercase with underscores between words. This isn’t just a formality — this style improves readability and helps prevent accidental changes. For example, use PI instead of pi, and TIMEOUT_SECONDS instead of timeout. Never use one-letter abbreviations or abstract names like X, VAL, or TMP. Names should be self-explanatory.

How to import constants in Python?

It’s best to place all constants in a separate constants.py file. Then, in the required modules, use import statements like:

from constants import API_KEY, TIMEOUT

Or, to avoid name conflicts:


    import constants
    print(constants.API_KEY) 

This approach makes your code modular and readable, especially in team projects.

How to store constants in Python?

Constants can be stored in standard .py files, JSON or YAML files (if loaded at runtime), or in environment variables. The best approach is to use a constants.py module where constants are defined at the top level. For sensitive data (like API keys), it's recommended to use environment variables via os.environ.

Are there ways to truly protect constants from being changed?

At the language level — no. Python doesn’t support immutable variables. But you can use named tuples, classes with @property (without a setter), or freezing via types.MappingProxyType. These methods protect data from being overwritten but add complexity. In practice, style and separating constants into modules is usually sufficient.

Should constants be grouped in classes or modules?

Yes. Grouping by meaning helps navigation and simplifies maintenance. For example, you can create a settings.py file with sections like DATABASE, AUTH, API, or use wrapper classes. This is especially useful for separating environments: dev, test, prod.

Can constants have complex data types like lists or dicts?

Yes. A constant can be any type — list, dictionary, tuple, even an object. The key is not to modify its contents. For example, a dictionary DEFAULT_HEADERS with HTTP headers can be declared as a constant as long as it isn’t modified during runtime. For immutability, use frozenset, namedtuple, or tuples.