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&#39;ll then have a few hundred Foos in my database. Then I&#39;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&#39;t work with existing Foo objects, as they won&#39;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, &#39;b_cache&#39;): 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 &#39;b_cache&#39; 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&#39;ll have to have the code all</div><div>over, and it won&#39;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, &#39;b_cache&#39;): 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&#39;s the best practice for this sort of thing, in general? </div>
<div><br></div><div>Thanks,</div><div>- Claudiu</div>