On Sun, 08 Nov 2009 14:41:27 -0800, markolopa wrote: > Hi, > > Could you please give me some advice on the piece of code I am writing? > > My system has several possible outputs, some of them are not always > needed. I started to get confused with the code flow conditions needed > to avoid doing unnecessary work.
How many dozens of man-hours (yours, and the people who have to maintain the software after you have moved on) of confusion are you going to spend to avoid how many microseconds of execution time? So what if your system takes 35ms instead of 18ms to calculate the result? As Tony Hoare famously said: "We should forget about the small efficiencies, say about 97% of the time: Premature optimization is the root of all evil." Of course, all of this assumes that the routines you are trying to avoid calling don't require hours of running time each time you call them... > So I am trying to restructure it using lazy evaluation. Oh great, avoiding confusion with something even more confusing. > - Is there a more standard (pythonic) way to do what I am trying to do? Yes. Avoid it. Do the simplest thing that works until you *know* -- because you have profiled it -- that it is too slow. Until then, all that complication you've built, all that over-engineered jungle of classes and abstract classes, is unnecessary. I find it beyond all credibility that your data is so complicated that you need a plug-in system just to manage the methods you need to calculate your data. Just create some properties, like this one: class Example(object): def __init__(self, birth_year): self.birth_year = birth_year @property def age(self): return 2009 - self.birth_year # FIXME -- it won't be 2009 forever And there you have a lazily-evaluated age property. Not complicated enough? The 3ms it takes to calculate the age is too long? Cache it! class Example(object): def __init__(self, birth_year): self.birth_year = birth_year self._age = None @property def age(self): a = self._age if a is None: a = 2009 - self.birth_year self._age = a return a Now all you need is to invalidate the cache if the birth_year changes. So you make birth_year a property too: class Example(object): def __init__(self, birth_year): self.birth_year = birth_year @property def birth_year(self): return self._birth_year @property.setter # Requires Python 2.6. Also untested. def birth_year(self, year): self._birth_year = year self._age = None @property def age(self): a = self._age if a is None: a = 2009 - self.birth_year self._age = a return a > Are there libraries, design patterns, functional programming structures > to use to achieve what I am looking for (i.e. am I trying to reinvent > the wheel)? The most important buzzwords you want are YAGNI and Premature Generalisation, and perhaps a touch of Architecture Astronaut: http://www.joelonsoftware.com/items/2008/05/01.html > - Is the coding style good? > - Can I avoid the eval command in Repository.add_routine? What I want > there is to be able to have a generic code for the repository which does > not depend on the files containing the routines I want it to hold. You mean the exec? cmd = "from %s import %s\nroutine = %s()" % (file_name, class_name, class_name) exec(cmd) # XXX: ugly Yes. Untested: module = __import__(filename) class_object = getattr(module, class_name) routine = class_object() Of course you can turn that into a one-liner: routine = getattr(__import__(filename), class_name)() -- Steven -- http://mail.python.org/mailman/listinfo/python-list