Defining Constants
Credit: Alex Martelli
Problem
You need to define module-level variables that client code cannot accidentally rebind (i.e., named constants).
Solution
In Python 2.1 and later, you can install any instance as if it was a
module. Just put the following in const.py:
class _const:
class ConstError(TypeError): pass
def _ _setattr_ _(self, name, value):
if self._ _dict_ _.has_key(name):
raise self.ConstError, "Can't rebind const(%s)"%name
self._ _dict_ _[name] = value
def _ _delattr_ _(self, name):
if self._ _dict_ _.has_key(name):
raise self.ConstError, "Can't unbind const(%s)"%name
raise NameError, name
import sys
sys.modules[_ _name_ _] = _const( )Now any client code can import const, then bind an
attribute on the const module just once, as
follows:
const.magic = 23
Once the attribute is bound, the program cannot accidentally rebind or unbind it:
const.magic = 88 # would raise const.ConstError del const.magic # would raise const.ConstError
Discussion
In Python, variables can be rebound at will, and modules
don’t let you define special methods such as an
instance’s _ _setattr_ _ to stop
rebinding. An easy solution (in Python 2.1 and later) is to set up an
instance as if it was a module.
In Python 2.1 and later, no check is made to force entries in
sys.modules to be actual module objects. You can
install an instance object there and take advantage of
attribute-access special methods (e.g., to prevent rebinding, to
synthesize attributes on the fly in _ _getattr_ _, and so ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access