Hello all,<div><br></div><div>It is often the case that I have a Persistent object that evolves over time. E.g., it might start off as this:</div><div><br></div><div> class Foo(Persistent):</div><div> def __init__(self, a):</div>
<div> self.a = a</div><div> def calc_it(self, b):</div><div> return expensive_function(a, b)</div><div><br></div><div>I'll then have a few hundred Foos in my database. Then I'll want to modify the object, for example to cache the previous calculation. </div>
<div>That is, I want this to be the case, now:</div><div><br></div><div><div> class Foo(Persistent):</div><div> def __init__(self, a):</div><div> self.a = a</div><div> self.b_cache = PersistentDict()</div>
<div> def calc_it(self, b):</div><div> if b in self.b_cache: return self.b_cache[b]</div><div> res = expensive_function(a, b)</div><div> self.b_cache[b] = res</div><div> return res</div>
<div><br></div><div>However, this won't work with existing Foo objects, as they won't have the `b_cache` attribute. Thus I have two options. One is</div><div>to make the modifications backwards-compatible, e.g.:</div>
<div><br></div><div><div> class Foo(Persistent):</div><div> def __init__(self, a):</div><div> self.a = a</div><div> self.b_cache = PersistentDict()</div><div> def calc_it(self, b):</div>
<div> if not hasattr(self, 'b_cache'): self.b_cache = PersistentDict()</div><div><br></div><div> if b in self.b_cache: return self.b_cache[b]</div><div> res = expensive_function(a, b)</div>
<div> self.b_cache[b] = res</div><div> return res</div></div><div><br></div><div>The other is to go through the database and add 'b_cache' to all the existing objects. Neither of these is really appealing.</div>
<div>The former is OK, but if I have multiple functions that want to use the new functionality I'll have to have the code all</div><div>over, and it won't be obviously separated. The latter is rather annoying as I have to figure out wherever I have Foos and</div>
<div>write throwaway code to change them all. </div><div><br></div><div>Ideally I could do something like this:</div><div><br></div><div><div> class Foo(Persistent):</div><div> def __init__(self, a):</div><div> self.a = a</div>
<div> self.b_cache = PersistentDict()<br><br></div><div> def __just_loaded__(self):</div><div><div> if not hasattr(self, 'b_cache'): self.b_cache = PersistentDict()</div><br class="Apple-interchange-newline">
</div><div> def calc_it(self, b):</div><div><br></div><div> if b in self.b_cache: return self.b_cache[b]</div><div> res = expensive_function(a, b)</div><div> self.b_cache[b] = res</div>
<div> return res</div></div><br class="Apple-interchange-newline"></div><div>That is, a function called whenever the object is loaded, that does all the necessary backwards-compatibility</div><div>work right there. It separates the backwards-compat code cleanly, and also only updates the objects</div>
<div>as-needed... though still a minor performance hit as it does the check each time the object is loaded.</div><div><br></div><div>Is there a way to do that last option? What's the best practice for this sort of thing, in general? </div>
<div><br></div><div>Thanks,</div><div>- Claudiu</div>