On Mon, 28 Feb 2005 23:08:04 GMT, Andrew Dalke <[EMAIL PROTECTED]> wrote:
> On Mon, 28 Feb 2005 15:50:22 -0500, Dan Sommers wrote: >> The reason their code is so inflexible is that they've filled their >> classes with boiler plate get/set methods. >> >> Why do users of classes need such access anyway? If my class performs >> useful functions and returns useful results, no user of my class should >> care about its attributes. If I "have to" allow access to my attributes >> in order that my users be happy, then I did something else wrong when I >> designed the class and its public interface in the first place. > Consider an interface to a temperature controller. It will > have several properties: > - current temperature (read only) > - target temperature (read/write) > - various tuning parameters that affect the rate of change, > stability, etc.; eg, lookup details on a PID controller > These are properties of the temperature controller object. > In Python these properties are traditionally mapped to attributes. > Under languages that don't have a __getattr__/"property" mechanism > for separating interface from implementation these are implemented > via get/set accessor methods. > It is very often useful to change the temperature setting of > a controller over time. Eg, a chemical protocol might say > "warm from 50 to 80 over a period of 30 minutes, 1 degree > per minute". > In Python that might be written as: > temp_controller = TemperatureController("/dev/com3") > temp_controller.target = 50 > print "Bringing reactor to", temp_controller.target > while 1: > print "Current temperature is", temp_controller.current > if abs(temp_controller.current - temp_controller.target) < 0.1: > break > time.sleep(30) > raw_input("Insert sample and press the <enter> key: ") > for temp in range(51, 81): > print "Raising reactor temperature to", temp > temp_controller.target = temp > time.sleep(60) > if abs(temp_controller.current - temp) > 0.1: > print "Variance too high!", temp_controller.current > print "DONE!" > What's wrong with the use of attributes in this case and how > would you write your interface? I think I'd add a change_temperature_to method that accepts the target temperature and some sort of timing information, depending on how the rest of the program and/or thread is structured. It might turn into two or three methods, depending on whether I can afford to block while waiting, or what kind of intermediate feedback and/or error handling I want (or one method with some carefully chosen default arguments). I don't know how that device driver works, but it might look something like this: def change_temperature_to( self, target, seconds_between_checks ): print 'target temperature:', target tell_the_device_to_change( ) while 1: current = read_the_temperature_from_the_device( ) print 'current temperature:', current if abs( current - target ) < 0.1: break time.sleep( seconds_between_checks ) Obviously, that code is untested! ;-) In the case of simply reading the current temperature, and not knowing what's inside that device driver, I'd still lean away from exposing a current temperature attribute directly. I think part of my thinking comes from my old Pascal days, when it made me cringe to think that "x:=b;" might actually execute a subroutine rather than just copy some memory around. I'm not saying that my applications *never* access my objects' attributes directly, just that it's one of those things that raises at least a yellow flag in my mind. Regards, Dan -- Dan Sommers <http://www.tombstonezero.net/dan/> Îâ à Îâ à c = 1 -- http://mail.python.org/mailman/listinfo/python-list