How do I create a constant in Python?
No there is not. You cannot declare a variable or value as constant in Python. Just don't change it.
If you are in a class, the equivalent would be:
class Foo(object): CONST_NAME = "Name"
if not, it is just
CONST_NAME = "Name"
But you might want to have a look at the code snippet Constants in Python by Alex Martelli.
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 Finala: Final = 1# Executes fine, but mypy will report an error if you run mypy on this:a = 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 0xDEADBEEFCONST = _Const()print CONST.FOO##3131964110CONST.FOO = 0##Traceback (most recent call last):## ...## CONST.FOO = 0##TypeError: None
Code Explanation:
- 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. - The setter function raises a TypeError so it's read-only
- 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): @apply def FOO(): def fset(self, value): raise TypeError def fget(self): return 0xBAADFACE return property(**locals())CONST = _Const()print CONST.FOO##3131964110CONST.FOO = 0##Traceback (most recent call last):## ...## CONST.FOO = 0##TypeError: None
Note that the @apply decorator seems to be deprecated.
- To define the identifier FOO, firs define two functions (fset, fget - the names are at my choice).
- Then use the built-in
property
function to construct an object that can be "set" or "get". - Note hat the
property
function's first two parameters are namedfset
andfget
. - 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
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.pi3.14>>> constants.pi = 3Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: can't set attribute