As you review this, please keep in mind I'm using Jython 2.1 as shipped with IBM's WebSphere 7.0 (their latest-and-greatest). I don't have decorators, properties, new style objects, or any other Python feature invented in the last decade.
Problem:
Using WebSphere's Jython interface to determine app server configuration information is not exactly fast. I had already begun work on a simple Jython module to encapsulate the convoluted WebSphere Jython API when I decided to try and cache the results of each method invocation. WebSphere configuration details tend not to change very often.
Inspired by Python 3.2's @functools.lru_cache and Python 2.2's properties I came up with:
from org.python.core import PyString, PyTuple
class Getter:
def getter(self,attr,valid_attrs):
if attr == 'valid_attrs': return valid_attrs
if attr not in valid_attrs.keys(): raise AttributeError
attr_value = None
if type(valid_attrs[attr]) == PyString:
function = getattr(self,valid_attrs[attr])
attr_value = function()
elif type(valid_attrs[attr]) == PyTuple:
function = getattr(self,valid_attrs[attr][0])
args = []
kwargs = {}
for arg in valid_attrs[attr][1:]:
if type(arg) == PyTuple:
if len(arg) > 2:
err = ('Named argument tuple %s in %s length > 2.'
% (arg, self.__class__.__name__ ))
raise NameError(err)
kwargs[arg[0]] = arg[1]
elif type(arg) == PyString:
args.append(arg)
else:
err = ('Unknown argument in %s __getattr__ dispatch list'
% self.__class__.__name__ )
raise NameError(err)
attr_value = function(*args,**kwargs)
else:
raise AttributeError
return attr_value
class App(Getter):
def __init__(self, name=None):
if name:
self.app_name = name
else:
print 'App instance requires name.'
raise NameError
def __getattr__(self,attr):
valid_attrs = { 'app_id': ('get_app_id'),
'deployed_nodes': ('get_deployed_nodes'),
'deployed_servers': ('get_deployed_servers'),
}
attr_value = Getter.getter(self,attr,valid_attrs)
setattr(self,attr,attr_value)
return attr_value
def get_app_id(self):
return AdminConfig.getid('/Deployment: %s/' % self.app_name)
def get_deployed_node(self):
### ...
def get_deployed_servers(self):
### ...
As I use this in other classes I change the function dispatch dict (valid_attrs
) as needed.
Is this an evil abuse of __getattr__
? Next to code execution speed, I'm most worried about maintainability. Does this trigger a "WTF?" Or, does it make sense when viewed against the limitations of Jython 2.1 and features, such as @property, found in newer versions?