10
\$\begingroup\$

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?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 16, 2011 at 19:33
\$\endgroup\$
1
  • 4
    \$\begingroup\$ Were I prone to making uneducated and accusatory statements, I would venture to say that WebSphere is the WTF. Instead, I will just wonder what their rationale is in shipping such an age-old version of Jython. Maybe not very many people are using Jython with WebSphere? \$\endgroup\$ Commented Mar 18, 2011 at 5:29

1 Answer 1

3
\$\begingroup\$

I'd say calling self.setattr from __getattr__(self, ) is borderline abuse in itself.

I guess you are trying to implement lazy attributes, right?

However in your case valid attributes are constant and their values appear constant too, so why not set them at class "declaration" time?

Also, python syntax for a tuple with 1 element is (1,) not (1) that you have in valid attrs extensively.

amon
12.7k37 silver badges67 bronze badges
answered Feb 7, 2012 at 9:53
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.