Skip to content

Python resources as Java-like properties files

November 24, 2009

BuildingSI’s application stack is Linux-Tomcat-MySQL-Java Servlet/Python/Wicket.  Wicket, Log4j, Tomcat etc. use of Java properties files to manage resources and Localized resources.  Because I am working in this framework all of the time, I decided to write a small base class for all of my Python objects that allows the Java-like properties file use for Python.

Of course, with pretty code formatting, managing string constants and varying configurations within your Python code is not as inconvenient as with a compiled language. The main advantage is uniformity.  During maintenance or message changing tasks, you merely edit all of the *.properties files at once.  A secondary advantage has been the ability to use identical code for staging and production by using platform/environment-dependent properties like,

"SOURCE.hostname="/cygdrive/c/..."

accessed by the Python code snippet,

hostname = os.environ['HOSTNAME']
SOURCE = self.getString("SOURCE." + hostname)

I haven’t worked out Localization analogous to Java resources, but it seems like a natural extension.

To use the code, just add the module res to your PYTHON_PATH and use it as a base class for each object (named like the module, if you want foo.py and foo.properties, for example).

# Resource files are named after class:
# class_name.properties
#
# If this class is the base class, then properties
# file is required.
# Logging is standard Python logging framework
import sys

class res:
    def __init__(self, logger=None):
        self.logger = logger
        self.resMap = {}
        filename = ''.join([sys.path[0],'/',self.__class__.__name__,".properties"])
        if self.logger is not None:
            self.logger.info("opening properties file %s"%filename)
        try:
            f = open(filename, 'rb')
            for prop in f:
                if prop[0] <> "#" and prop[0] <> '\n':
                    list = prop.split("=")
                    value = ''
                    for i in range(1,len(list)):
                        value += list[i] + "="
                    key = list[0]
                    value = value[:-1]
                    self.resMap[key] = value.strip("\n\r '\"").strip('\n\r')
                    if self.logger is not None:
                        self.logger.debug("property %s set to '%s'"%(key, self.resMap[key]))
        except IOError:
            if self.logger is not None:
                self.logger.info("unable to read resource file %s"%filename)
            else:
                sys.stderr.write("unable to read resource file %s\n"%filename)

    def getString(self, key):
        if key in self.resMap:
            return self.resMap[key]
        else:
            if self.logger is not None:
                self.logger.error("resource %s missing"%key )
            else:
                sys.stderr.write("resource %s missing\n"%key )
        return ""

Be sure to call res’s __init__ function for your class. Notice you can call it with a logger reference if you are using Python logging.

class test1(res.res):
    def __init__(self):
        res.res.__init__(self)

To access a property,

case1.getString("key1")

where the properties file looks just like it’s Java counterpart. If you try it out or make any extensions, let me know how it goes.

Advertisement

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: