Hi, I'm Harlin and welcome to my blog. I write about Python, Alfresco and other cheesy comestibles.

Python: How to Make Use of Constants and Assertions

I knew there was no such thing built in to Python for one to create a constant but of course, I happened to find a hack by Alex Martelli here.

Copying verbatim and shamelessly, here it is:

# Put 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
import sys
sys.modules[__name__]=_const()

# that's all -- now any client-code can
import const
# and bind an attribute ONCE:
const.magic = 23
# but NOT re-bind it:
const.magic = 88      # raises const.ConstError
# you may also want to add the obvious __delattr__

How about that?

A lot of devs are ok with Python doing dynamic typing. After all, it's very predictable. A number without quotes will cause Python to reserve the type as an integer, a decimal number reserves a float and a quoted piece of text becomes a string:

a = 6  # (int)
a = "7"  # (str)
a = 6.0  # (float)

But, it seems to bother folks that there is no type checking built-in out of the box for variables passed to functions and the like.

def say_hi(name):
    print("Hello " + name)

What if "name" is a not a string when passed? The print statement will throw a concatenation error. If you give it a 5 (and not a "5"), it will throw an error. And yes, you can use %d or '...{}'.format(name) but you should get the point.

So, we can use assertions to make sure that name is what print() is expecting it to be. This is an extremely weak example but here it is anyways:

def say_hi(name):
    assert is instance(name, str), \
        'Param "name" is wrong type: expected "string"'
    print("Hello " + name)
>>> say_hi("Harlin")
Hello Harlin
>>> say_hi(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in say_hi
AssertionError: Param "name" is wrong type: expected "string"

A little bit ugly perhaps but gets the job done.

Any Comments, Always Welcome!