How Do I Create a Constant in Python?

How do I declare a constant in Python?

In Java, we do:

public static final String CONST_NAME = "Name";
6

44 Answers

You cannot declare a variable or value as constant in Python.


To indicate to programmers that a variable is a constant, one usually writes it in upper case:

CONST_NAME = "Name"

To raise exceptions when constants are changed, see Constants in Python by Alex Martelli. Note that this is not commonly used in practice.


As of Python 3.8, there's a typing.Final variable annotation that will tell static type checkers (like mypy) that your variable shouldn't be reassigned. This is the closest equivalent to Java's final. However, it does not actually prevent reassignment:

from typing import Final

a: Final[int] = 1

# Executes fine, but mypy will report an error if you run mypy on this:
a = 2
2

There's no const keyword as in other languages, however it is possible to create a Property that has a "getter function" to read the data, but no "setter function" to re-write the data. This essentially protects the identifier from being changed.

Here is an alternative implementation using class property:

Note that the code is far from easy for a reader wondering about constants. See explanation below.

def constant(f):
    def fset(self, value):
        raise TypeError
    def fget(self):
        return f()
    return property(fget, fset)

class _Const(object):
    @constant
    def FOO():
        return 0xBAADFACE
    @constant
    def BAR():
        return 0xDEADBEEF

CONST = _Const()

print(hex(CONST.FOO))  # -> '0xbaadfaceL'

CONST.FOO = 0
##Traceback (most recent call last):
##  File "example1.py", line 22, in <module>
##    CONST.FOO = 0
##  File "example1.py", line 5, in fset
##    raise TypeError
##TypeError

Code Explanation:

  1. Define a function constant that takes an expression, and uses it to construct a "getter" - a function that solely returns the value of the expression.
  2. The setter function raises a TypeError so it's read-only
  3. Use the constant function we just created as a decoration to quickly define read-only properties.

And in some other more old-fashioned way:

(The code is quite tricky, more explanations below)

class _Const(object):
    def FOO():
        def fset(self, value):
            raise TypeError
        def fget(self):
            return 0xBAADFACE
        return property(**locals())
    FOO = FOO()  # Define property.

CONST = _Const()

print(hex(CONST.FOO))  # -> '0xbaadfaceL'

CONST.FOO = 0
##Traceback (most recent call last):
##  File "example2.py", line 16, in <module>
##    CONST.FOO = 0
##  File "example2.py", line 6, in fset
##    raise TypeError
##TypeError
  1. To define the identifier FOO, firs define two functions (fset, fget - the names are at my choice).
  2. Then use the built-in property function to construct an object that can be "set" or "get".
  3. Note hat the property function's first two parameters are named fset and fget.
  4. Use the fact that we chose these very names for our own getter & setter and create a keyword-dictionary using the ** (double asterisk) applied to all the local definitions of that scope to pass parameters to the property function
0

In Python instead of language enforcing something, people use naming conventions e.g __method for private methods and using _method for protected methods.

So in same manner you can simply declare the constant as all caps, e.g.:

MY_CONSTANT = "one"

If you want that this constant never changes, you can hook into attribute access and do tricks, but a simpler approach is to declare a function:

def MY_CONSTANT():
    return "one"

Only problem is everywhere you will have to do MY_CONSTANT(), but again MY_CONSTANT = "one" is the correct way in Python (usually).


You can also use namedtuple() to create constants:

>>> from collections import namedtuple
>>> Constants = namedtuple('Constants', ['pi', 'e'])
>>> constants = Constants(3.14, 2.718)
>>> constants.pi
3.14
>>> constants.pi = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
2

I've recently found a very succinct update to this which automatically raises meaningful error messages and prevents access via __dict__:

class CONST(object):
    __slots__ = ()
    FOO = 1234

CONST = CONST()

# ----------

print(CONST.FOO)    # 1234

CONST.FOO = 4321              # AttributeError: 'CONST' object attribute 'FOO' is read-only
CONST.__dict__['FOO'] = 4321  # AttributeError: 'CONST' object has no attribute '__dict__'
CONST.BAR = 5678              # AttributeError: 'CONST' object has no attribute 'BAR'

We define over ourselves as to make ourselves an instance and then use slots to ensure that no additional attributes can be added. This also removes the __dict__ access route. Of course, the whole object can still be redefined.

Edit - Original solution

I'm probably missing a trick here, but this seems to work for me:

class CONST(object):
    FOO = 1234

    def __setattr__(self, *_):
        pass

CONST = CONST()

#----------

print CONST.FOO    # 1234

CONST.FOO = 4321
CONST.BAR = 5678

print CONST.FOO    # Still 1234!
print CONST.BAR    # Oops AttributeError

Creating the instance allows the magic __setattr__ method to kick in and intercept attempts to set the FOO variable. You could throw an exception here if you wanted to. Instantiating the instance over the class name prevents access directly via the class.

It's a total pain for one value, but you could attach lots to your CONST object. Having an upper class, class name also seems a bit grotty, but I think it's quite succinct overall.

0

Python doesn't have constants.

Perhaps the easiest alternative is to define a function for it:

def MY_CONSTANT():
    return 42

MY_CONSTANT() now has all the functionality of a constant (plus some annoying braces).

6

Properties are one way to create constants. You can do it by declaring a getter property, but ignoring the setter. For example:

class MyFinalProperty(object):

    @property
    def name(self):
        return "John"

You can have a look at an article I've written to find more ways to use Python properties.

2

In addition to the two top answers (just use variables with UPPERCASE names, or use properties to make the values read-only), I want to mention that it's possible to use metaclasses in order to implement named constants. I provide a very simple solution using metaclasses at GitHub which may be helpful if you want the values to be more informative about their type/name:

>>> from named_constants import Constants
>>> class Colors(Constants):
...     black = 0
...     red = 1
...     white = 15
...
>>> c = Colors.black
>>> c == 0
True
>>> c
Colors.black
>>> c.name()
'black'
>>> Colors(0) is c
True

This is slightly more advanced Python, but still very easy to use and handy. (The module has some more features, including constants being read-only, see its README.)

There are similar solutions floating around in various repositories, but to the best of my knowledge they either lack one of the fundamental features that I would expect from constants (like being constant, or being of arbitrary type), or they have esoteric features added that make them less generally applicable. But YMMV, I would be grateful for feedback. :-)

0

Edit: Added sample code for Python 3

Note: this other answer looks like it provides a much more complete implementation similar to the following (with more features).

First, make a metaclass:

class MetaConst(type):
    def __getattr__(cls, key):
        return cls[key]

    def __setattr__(cls, key, value):
        raise TypeError

This prevents statics properties from being changed. Then make another class that uses that metaclass:

class Const(object):
    __metaclass__ = MetaConst

    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

Or, if you're using Python 3:

class Const(object, metaclass=MetaConst):
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

This should prevent instance props from being changed. To use it, inherit:

class MyConst(Const):
    A = 1
    B = 2

Now the props, accessed directly or via an instance, should be constant:

MyConst.A
# 1
my_const = MyConst()
my_const.A
# 1

MyConst.A = 'changed'
# TypeError
my_const.A = 'changed'
# TypeError

Here's an example of above in action. Here's another example for Python 3.

PEP 591 has the 'final' qualifier. Enforcement is down to the type checker.

So you can do:

MY_CONSTANT: Final = 12407

Note: Final keyword is only applicable for Python 3.8 version

2

You can use a namedtuple as a workaround to effectively create a constant that works the same way as a static final variable in Java (a Java "constant"). As workarounds go, it's sort of elegant. (A more elegant approach would be to simply improve the Python language --- what sort of language lets you redefine math.pi? -- but I digress.)

(As I write this, I realize another answer to this question mentioned namedtuple, but I'll continue here because I'll show a syntax that more closely parallels what you'd expect in Java, as there is no need to create a named type as namedtuple forces you to do.)

Following your example, you'll remember that in Java we must define the constant inside some class; because you didn't mention a class name, let's call it Foo. Here's the Java class:

public class Foo {
  public static final String CONST_NAME = "Name";
}

Here's the equivalent Python.

from collections import namedtuple
Foo = namedtuple('_Foo', 'CONST_NAME')('Name')

The key point I want to add here is that you don't need a separate Foo type (an "anonymous named tuple" would be nice, even though that sounds like an oxymoron), so we name our namedtuple _Foo so that hopefully it won't escape to importing modules.

The second point here is that we immediately create an instance of the nametuple, calling it Foo; there's no need to do this in a separate step (unless you want to). Now you can do what you can do in Java:

>>> Foo.CONST_NAME
'Name'

But you can't assign to it:

>>> Foo.CONST_NAME = 'bar'
…
AttributeError: can't set attribute

Acknowledgement: I thought I invented the namedtuple approach, but then I see that someone else gave a similar (although less compact) answer. Then I also noticed What are "named tuples" in Python?, which points out that sys.version_info is now a namedtuple, so perhaps the Python standard library already came up with this idea much earlier.

Note that unfortunately (this still being Python), you can erase the entire Foo assignment altogether:

>>> Foo = 'bar'

(facepalm)

But at least we're preventing the Foo.CONST_NAME value from being changed, and that's better than nothing. Good luck.

0

Here is an implementation of a "Constants" class, which creates instances with read-only (constant) attributes. E.g. can use Nums.PI to get a value that has been initialized as 3.14159, and Nums.PI = 22 raises an exception.

# ---------- Constants.py ----------
class Constants(object):
    """
    Create objects with read-only (constant) attributes.
    Example:
        Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0)
        print 10 + Nums.PI
        print '----- Following line is deliberate ValueError -----'
        Nums.PI = 22
    """

    def __init__(self, *args, **kwargs):
        self._d = dict(*args, **kwargs)

    def __iter__(self):
        return iter(self._d)

    def __len__(self):
        return len(self._d)

    # NOTE: This is only called if self lacks the attribute.
    # So it does not interfere with get of 'self._d', etc.
    def __getattr__(self, name):
        return self._d[name]

    # ASSUMES '_..' attribute is OK to set. Need this to initialize 'self._d', etc.
    #If use as keys, they won't be constant.
    def __setattr__(self, name, value):
        if (name[0] == '_'):
            super(Constants, self).__setattr__(name, value)
        else:
            raise ValueError("setattr while locked", self)

if (__name__ == "__main__"):
    # Usage example.
    Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0)
    print 10 + Nums.PI
    print '----- Following line is deliberate ValueError -----'
    Nums.PI = 22

Thanks to @MikeGraham 's FrozenDict, which I used as a starting point. Changed, so instead of Nums['ONE'] the usage syntax is Nums.ONE.

And thanks to @Raufio's answer, for idea to override __ setattr __.

Or for an implementation with more functionality, see @Hans_meine 's named_constants at GitHub

1

A tuple technically qualifies as a constant, as a tuple will raise an error if you try to change one of its values. If you want to declare a tuple with one value, then place a comma after its only value, like this:

my_tuple = (0 """Or any other value""",)

To check this variable's value, use something similar to this:

if my_tuple[0] == 0:
    #Code goes here

If you attempt to change this value, an error will be raised.

from enum import Enum
class StringConsts(str,Enum):
    ONE='one'
    TWO='two'

print(f'Truth is  {StringConsts.ONE=="one"}') #Truth is True
StringConsts.ONE="one" #Error: Cannot reassign

This mixin of Enum and str gives you the power of not having to reimplement setattr (through Enum) and comparison to other str objects (through str).

This might deprecate completely.

3

Here it is a collection of idioms that I created as an attempt to improve some of the already available answers.

I know the use of constant is not pythonic, and you should not do this at home!

However, Python is such a dynamic language! This forum shows how it is possible the creation of constructs that looks and feels like constants. This answer has as the primary purpose to explore what can be expressed by the language.

Please do not be too harsh with me :-).

For more details I wrote a accompaniment blog about these idioms.

In this post, I will call a constant variable to a constant reference to values (immutable or otherwise). Moreover, I say that a variable has a frozen value when it references a mutable object that a client-code cannot update its value(s).

A space of constants (SpaceConstants)

This idiom creates what looks like a namespace of constant variables (a.k.a. SpaceConstants). It is a modification of a code snippet by Alex Martelli to avoid the use of module objects. In particular, this modification uses what I call a class factory because within SpaceConstants function, a class called SpaceConstants is defined, and an instance of it is returned.

I explored the use of class factory to implement a policy-based design look-alike in Python in stackoverflow and also in a blogpost.

def SpaceConstants():
    def setattr(self, name, value):
        if hasattr(self, name):
            raise AttributeError(
                "Cannot reassign members"
            )
        self.__dict__[name] = value
    cls = type('SpaceConstants', (), {
        '__setattr__': setattr
    })
    return cls()

sc = SpaceConstants()

print(sc.x) # raise "AttributeError: 'SpaceConstants' object has no attribute 'x'"
sc.x = 2 # bind attribute x
print(sc.x) # print "2"
sc.x = 3 # raise "AttributeError: Cannot reassign members"
sc.y = {'name': 'y', 'value': 2} # bind attribute y
print(sc.y) # print "{'name': 'y', 'value': 2}"
sc.y['name'] = 'yprime' # mutable object can be changed
print(sc.y) # print "{'name': 'yprime', 'value': 2}"
sc.y = {} # raise "AttributeError: Cannot reassign members"

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.