Python resources as Java-like properties files
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.
Trackbacks