This topic is about the OO style employed by Webware. It is a long topic and some may find it boring, but it affects the programmatic interface to Webware, so I felt it should be posted to -discuss rather than -devel for all to see.
Here is the main point: With the advent of Python 2.2, we have the "properties style" as described here: http://www.python.org/2.2/descrintro.html#property Should Webware adopt the "properties style"? + Easy to read and write. + Would make Webware source more Pythonic. + Preserves "opaqueness". + As fast as mixed style and faster than other styles. - Existing code bases would require updates. - Would required Python 2.2 OR that we provide the GetterSetter helper for 2.0 and 2.1 users (with the understanding that performance might take a dive for such users). And here is a detailed background if you care to read further: When writing classes, the "mixed style" is to use both data attributes and methods to access values: # Vector.py class Vector: def __init__(self): self.x = self.y = 0 def length(self): return math.sqrt(self.x*self.x + self.y*self.y) # prog.py v = Vector() v.x = 1 v.y = 4 print v.length() I don't like the mixed style because if you switch a "foo" from a method to an attribute or the other way around, you break the interface: class Vector: def __init__(self): self.x = self.y = 0 def setX(self, x): self.x = x self._computerLength() def setY(self, y): self.y = y self._computeLength() def _computeLength(self): self.length = math.sqrt(self.x*self.x + self.y*self.y) Now prog.py is broken simply because we wanted to compute the length when X or Y are set (presumably we have determined it is asked for much more frequently than it is altered). Setting X and Y broke because they have to be methods now and asking for the length broke because it no longer requires paren()s. (Note: These code examples are neither perfect, nor tested. They are just to illustrate the issues.) Some people solve this by using the "getter-setter style": # GetterSetter.py class GetterSetter: def __getattr__(self, name): if not name.startswith('__'): method = getattr(self, 'get_' + name, None) if method: return method() raise AttributeError, name def __setattr__(self, name, value): if not name.startswith('__'): method = getattr(self, 'set_' + name, None) if method: method(value) self.__dict__[name] = value # Vector.py class Vector(GetterSetter): def __init__(self): self.x = self.y = 0 def set_x(self, value): self.__dict__['x'] = value # ^^ use self.__dict__ to avoid infinite recursion to __setattr__ self._computeLength() def set_y(self, value): self.__dict__['y'] = value self._computeLength() def _computeLength(self): self.length = math.sqrt(self.x*self.x + self.y*self.y) Pros and cons of getter-setter style: + Opaque: No code using Vector is broken. + Concise: Vector users can conveniently avoid the extra parens and "set" words and such that come with methods. eg. v.x = 5 and v.length instead of v.setX(5) and v.length() - Performance: Having experimented with this style in a recent project, I found it could be a major source of slow down. Particularly, __setattr__ adds a method call and extra Python byte code to every attribute assignment. My program slowed down by at least 10X. - Implementation: The use of self.__dict__['foo'] is ugly and forgetting it results in infinite recursion (quickly spotted of course). - Implementation: __getattr__ and __setattr__ are "asymmetric" in their design. The first is called as a last resort, the other is always called. This leads to some subtle issues in how you treat your attributes. Next we have the "encapsulation with methods" style which I guess I took from Smalltalk & Objective-C and is the current Webware style. Use methods for everything large and small. Pros and cons: + No code breaks due to simple interface changes. + Faster execution than the getter-setter style. + Generally encourages more protection of the object's data attributes. + Easy to understand - Slower execution than the mixed style. - More typing: obj.setFoo() obj.foo() self._foo In a recent, private project I started with the getter-setter style and found it more convenient than method encapsulation, but too expensive performance-wise. I then scaled back to the mixed style, but with the problems described above. Overall, I still liked the conciseness of both styles. I felt like coding was quicker and just as readable. The properties style seems to give all the pros and only legacy-related cons. See the beginning of the message. Reactions? -Chuck _______________________________________________ Webware-discuss mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/webware-discuss
