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