Skip to content

Understanding Constants in Python: Effortlessly Mastering Immutable Values

[

Python Constants: Improve Your Code’s Maintainability

In programming, the term constant refers to names representing values that don’t change during a program’s execution. Constants are a fundamental concept in programming, and Python developers use them in many cases. However, Python doesn’t have a dedicated syntax for defining constants. In practice, Python constants are just variables that never change.

To prevent programmers from reassigning a name that’s supposed to hold a constant, the Python community has adopted a naming convention: use uppercase letters. For every Pythonista, it’s essential to know what constants are, as well as why and when to use them.

In this tutorial, you’ll learn how to:

  • Properly define constants in Python
  • Identify some built-in constants
  • Use constants to improve your code’s readability, reusability, and maintainability
  • Apply different approaches to organize and manage constants in a project
  • Use several techniques to make constants strictly constant in Python

By learning to define and use constants, you’ll dramatically improve your code’s readability, maintainability, and reusability.

Understanding Constants and Variables

Variables and constants are two historical and fundamental concepts in computer programming. Most programming languages use these concepts to manipulate data and work in an effective and logical fashion. Variables and constants will probably be present in each project, app, library, or other piece of code that you’ll ever write.

What Variables Are

Variables in programming are used to store and manipulate data. They can hold different values during a program’s execution, and their values can change throughout the program. Variables have names that you choose, and you can assign values to those names.

What Constants Are

Constants, on the other hand, are names that represent values that do not change during a program’s execution. The value assigned to a constant remains the same throughout the program, and it cannot be modified. Constants provide a way to give meaningful names to important values in your code and make your code more readable and maintainable.

Why Use Constants

Using constants in your code has several benefits:

  1. Readability: Constants with meaningful names improve the readability of your code. For example, using PI instead of 3.14159 makes it clear that the value represents the mathematical constant.

  2. Maintainability: Constants make it easier to maintain your code. If you need to change a value that is used multiple times in your code, you only need to change it in one place—the constant’s definition.

  3. Reusability: Constants can be easily reused in different parts of your code or in other projects. By defining them once and using them multiple times, you ensure consistency and reduce the chance of introducing errors.

When Use Constants

You might want to use constants in the following situations:

  • Mathematical values: Constants like PI, E, or G in physics are good examples of constants that are used frequently and have clear meanings.

  • Configuration settings: Constants can be used to store configuration values such as API keys, database connection strings, or any other value that remains constant across multiple runs of your program.

  • Magic numbers: Magic numbers are hard-coded numeric values that appear in your code. They make the code harder to understand and maintain. By replacing magic numbers with named constants, you make your code more self-explanatory.

Defining Your Own Constants in Python

Python doesn’t have a built-in syntax for defining constants. In practice, constants in Python are just variables that are conventionally written in uppercase letters.

User-Defined Constants

To define your own constants in Python, simply assign a value to a name using uppercase letters. For example:

MAX_VALUE = 100

This defines a constant named MAX_VALUE with a value of 100. By convention, the name is written in uppercase letters to indicate that it’s intended to be a constant.

Module-Level Dunder Constants

You can also define constants at the module level, which means they can be accessed by any function or class within the module. To do this, define the constant directly in the module:

my_module.py
CONSTANT_VALUE = 42

In this example, CONSTANT_VALUE is a constant that can be accessed throughout the module.

Putting Constants Into Action

Now that you know how to define constants in Python, let’s see how you can use them to improve your code.

Replacing Magic Numbers for Readability

One common use case for constants is to replace magic numbers in your code. Magic numbers are hard-coded numeric values that have unclear meanings. By assigning those values to named constants, you make your code more self-explanatory.

For example, consider the following code snippet:

result = calculate_area(3.14159, radius)

The 3.14159 in this code is a magic number representing the mathematical constant π. By defining a constant named PI and using it in the code, you make it more readable:

PI = 3.14159
result = calculate_area(PI, radius)

Reusing Objects for Maintainability

Constants can also be used to reuse objects in your code. This can improve maintainability by ensuring that multiple instances of the same object are not created unnecessarily.

For example, suppose you have a function that creates a list with some default values:

def create_list():
return [0, 0, 0, 0]

Instead of creating a new list with [0, 0, 0, 0] every time the function is called, you can define a constant for the default list and reuse it:

DEFAULT_LIST = [0, 0, 0, 0]
def create_list():
return DEFAULT_LIST.copy()

This way, the list is created only once, improving performance and reducing memory usage.

Providing Default Argument Values

Constants can also be used to provide default values for function arguments. This makes the code more self-explanatory and reduces the need for comments or documentation to explain the default values.

For example, suppose you have a function that calculates the area of a rectangle. You can use constants to provide default values for the dimensions:

DEFAULT_WIDTH = 1.0
DEFAULT_HEIGHT = 1.0
def calculate_area(width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT):
return width * height

With this code, the default width and height of the rectangle are clear and can be easily changed if needed.

Handling Your Constants in a Real-World Project

As your projects grow in complexity, you’ll need to handle constants in a more organized and manageable way. Here are some approaches you can use:

When defining constants for a specific module or class, it’s a good practice to put them together with the related code. This makes it easier to understand and maintain the code.

For example, suppose you have a module for working with shapes that includes a constant for the maximum number of sides a shape can have:

class Shape:
MAX_SIDES = 10
def get_max_sides(self):
return self.MAX_SIDES

By defining the constant inside the Shape class, it’s clear that it is related to the concept of a shape.

Creating a Dedicated Module for Constants

For larger projects with many constants, it’s a good idea to create a dedicated module just for constants. This module can be imported whenever you need access to the constants in your code.

For example, you might have a module named constants.py that contains all the constants for your project:

constants.py
MAX_VALUE = 100
DEFAULT_WIDTH = 1.0
DEFAULT_HEIGHT = 1.0

In other modules, you can import the constants like this:

from constants import MAX_VALUE, DEFAULT_WIDTH, DEFAULT_HEIGHT

This approach keeps your code organized and makes it easy to locate and manage constants.

Storing Constants in Configuration Files

For configuration values that remain constant across multiple runs of your program, it’s a good practice to store them in separate configuration files. This allows you to easily change the values without modifying your code.

For example, you might have a configuration file named config.ini that contains constants for API keys:

config.ini
[API_KEYS]
KEY1 = abc123
KEY2 = xyz789

In your code, you can read the configuration file and access the constants using a library like configparser:

import configparser
config = configparser.ConfigParser()
config.read('config.ini')
key1 = config.get('API_KEYS', 'KEY1')
key2 = config.get('API_KEYS', 'KEY2')

Handling Constants as Environment Variables

Another approach to managing constants in your code is to use environment variables. Environment variables are values that are set in the operating system and can be accessed by your code.

To access environment variables in Python, you can use the os module:

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

By using environment variables for constants, you separate the configuration from your code and make it easier to deploy your code in different environments.

Exploring Other Constants in Python

In addition to user-defined constants, Python provides several built-in constants that you can use in your code. Here are some examples:

Built-in Constants

Python includes some built-in constants that provide useful information and functionality. Here are some examples:

  • True and False: The boolean values True and False represent the truth values of logic.
  • None: The constant None represents the absence of a value and is often used to indicate the absence of a return value in functions.
  • Ellipsis: The constant Ellipsis represents an ellipsis, which is used in slicing to indicate a range of values.
  • NotImplemented: The constant NotImplemented is used to indicate that a specific operation or method is not implemented or not applicable.
  • __debug__: The constant __debug__ is True if Python was run in debug mode and False otherwise.

Internal Dunder Names

Python uses some internal dunder names that represent specific values. These names start and end with double underscores. Here are some examples:

  • __name__: The __name__ attribute represents the name of the current module.
  • __file__: The __file__ attribute represents the path to the current module’s file.
  • __doc__: The __doc__ attribute contains the docstring of a module, class, function, or method.
  • __class__: The __class__ attribute represents the class that an instance belongs to.
  • __init__: The __init__ method is a special method that is automatically called when a new instance of a class is created.

Useful String and Math Constants

The math module in Python provides constants for mathematical operations. Here are some examples:

  • math.pi: The constant math.pi represents the mathematical constant π.
  • math.e: The constant math.e represents the mathematical constant e.
  • math.inf: The constant math.inf represents positive infinity.
  • math.nan: The constant math.nan represents a special floating-point value that is not a number.

Type-Annotating Constants

In Python, you can use type annotations to specify the types of variables, including constants. Type annotations improve code readability and can help catch potential errors early.

To annotate a constant, you can use the : operator followed by the type. For example:

MAX_VALUE: int = 100

This indicates that MAX_VALUE is of type int.

Defining Strict Constants in Python

While Python doesn’t have a built-in feature for enforcing constant behavior, there are several techniques you can use to make constants strictly constant in Python.

The .__slots__ Attribute

The .__slots__ attribute is a special attribute that allows you to define a fixed set of attributes for a class. By using .__slots__, you can prevent the creation of new attributes and enforce constant behavior for existing attributes.

The @property Decorator

The @property decorator allows you to define a method that can be accessed like an attribute. By using @property, you can enforce constant behavior for attributes by preventing their modification after they are set.

The namedtuple() Factory Function

The namedtuple() factory function from the collections module allows you to create lightweight classes that represent immutable data structures. By using namedtuple(), you can create constant-like objects that cannot be modified.

The @dataclass Decorator

The @dataclass decorator from the dataclasses module allows you to quickly define classes with pre-defined properties and methods. By using @dataclass, you can enforce constant behavior for properties by preventing their modification after they are set.

The .__setattr__() Special Method

The .__setattr__() special method allows you to control the assignment of attributes within a class. By using .__setattr__(), you can prevent the modification of attributes and enforce constant behavior.

Conclusion

Constants play an important role in maintaining readable, maintainable, and reusable code. By defining and using constants in your Python programs, you enhance code readability, performance, and maintainability. You also reduce the likelihood of introducing errors and increase the reusability of your code. Use the techniques and best practices outlined in this tutorial to effectively define and manage constants in your own Python projects.