Welcome, guest | Sign In | My Account | Store | Cart

A simple constant type which overrides the base integer type to provide a useful name on str().

Python, 31 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class constant(int):
    """A constant type which overrides base int to provide a useful name on str().
    Example:

    >>> STATUS_RUNNING = constant(0, 'running')
    >>> STATUS_RUNNING  
    0
    >>> str(STATUS_RUNNING)
    'running'
    >>>
    """

    def __new__(cls, value, name, doc=None):
        inst = super(constant, cls).__new__(cls, value)
        inst._name = name
        if doc is not None:
            inst.__doc__ = doc
        return inst

    def __str__(self):
        return self._name

    def __eq__(self, other):
        if isinstance(other, int):
            return int(self) == other
        if isinstance(other, str):
            return self._name == other
        return False

    def __ne__(self, other):
        return not self.__eq__(other)

This recipe can be useful in case integer-based constants are part of your public API. Consider the following situation:

>>> from somemodule import get_status, STATUS_RUNNING, STATUS_SLEEPING, STATUS_STOPPED
>>> get_status()
0
>>>

...to figure out what 0 actually means you would end up doing:

>>> status = get_status()
>>> if status == STATUS_RUNNING:
...     print 'running'
... elif status == STATUS_SLEEPING:
...     print 'sleeping'
... elif status == STATUS_STOPPED:
...     print 'stopped'
...
>>>

Instead, you can just do:

>>> from somemodule import get_status
>>> get_status()
0
>>> str(get_status())
'running'
>>>

Both int and str values can be used when comparing for equality (useful for serialization):

>>> st = constant(0, "running")
>>> st == 0
True
>>> st == 'running'
True

1 comment

s_h_a_i_o 9 years, 11 months ago  # | flag

Useful idea! Maybe you could write it as a decorator that would work on any class, not just int, because constants could be strings or even objects, rather than int.

If you change the name of the constant, you need change the name in your __init__(), so maybe the class could find the name in the module by itself ?

Created by Giampaolo Rodolà on Tue, 13 Dec 2011 (MIT)
Python recipes (4591)
Giampaolo Rodolà's recipes (15)

Required Modules

  • (none specified)

Other Information and Tasks