On Feb 6, 2:36 pm, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > jeremito a écrit : > > > > > On Feb 6, 10:59 am, "[EMAIL PROTECTED]" > > <[EMAIL PROTECTED]> wrote: > > >>On 6 fév, 16:23, "jeremito" <[EMAIL PROTECTED]> wrote: > > (snip) > >>>But I can't even get __setitem__ to run. > > >>of course, since your __new__ method returns a dict instance, not a xs > >>instance... > >>There are very few cases where you really need to override the __new__ > >>method. > > > The reason I create my object with __new__ instead of __init__ is > > because when I use __init__ when a value is set it calls __setitem__. > > This is what I want to happen, but not inside of __init__. Does this > > make sense? > > It would make sens - if you couldn't call dict.__setitem__ directly. > > > > > > > I'm sure there is a better/more pythonic way to do this, > > but I'm unsure of what it is. Can someone show me an example of how > > this should work? > > (snip) > >>>Is this what the __setitem__ method is for? > > >>Yes. But note that you you need to manually call the superclass's > >>overriden method - unless you > >>really want to replace it with your own, which is obviously not the > >>case here... > > >>Note that if someone manually changes the values of xG, xF, or xS, the > >>computed values of xA and/or xT > >>won't reflect this change. Is that what you want ? > > > Eventually (when I figure out how to use __setitem__) I will change > > what happens when xG, xF, or xS are changed so that it also changes xA > > and xT. > > Which is not the best way to go IMHO. Unless the computation is very > intensive (which doesn't seem to be the case here) or it's heavily used > in big loops *and* the perfs are not good enough, it's better to > recompute on the fly at read time. And if one of the above cases arises, > then it will be time to use memoization (ie: cache the result of > computation, invalidating the cache when needed). > > > > >>Finally, and if I may ask, what is your use-case for subclassing > >>dict ? You don't need this to implement a dict-like object, > >>and it might be simpler in your case to write an ordinary class, then > >>add support for the required subset of the dict interface. > > > Eventually I am going to add other features to my class (as I have > > mentioned) so I can't simply use a dict object. > > I already understood this. My question is : why do you want to > *subclass* dict. In Python, inheritence is only about implementation, > it's *not* needed for polymorphism to work. So you don't have to > subclass dict to have an object behaving (more or less, that's up to > you) like a dict. > > Here's an alternative implementation, so you get the idea. Note that it > behaves mostly like a dict (well, not totally, but since we don't know > which subset of the dict interface you need...), but also like a > 'standard' object, so you can use either cs.['xT'] or cs.xT with the > same result. > > class Xs(dict): > """ > Xs is a container object to hold information about cross sections. > """ > _computedkeys = 'xA', 'xT' > > def __init__(self, xS=1.0, xF=1.0, xG=1.0, nu=1.0, debug=0): > self.xS = xS > self.xF = xF > self.xG = xG > self.nu = nu > > # xA and xT as properties (AKA computed attributes) > def _get_xA(self): > return self.xG + self.xF > def _set_xA(self, dummy): > raise AttributeError( > "%s.xA is read-only" % self.__class__.__name__ > ) > xA = property(fset=_set_xA, fget=_get_xA) > > def _get_xT(self): > return self.xA + self.xS > def _set_xT(self, dummy): > raise AttributeError( > "%s.xT is read-only" % self.__class__.__name__ > ) > xT = property(fset=_set_xT, fget=_get_xT) > > # dict interface support, to be extended if needed > def __setitem__(self, key, value): > setattr(self, key, value) > > def __getitem__(self, key): > return getattr(self, key) > > def keys(self): > return self.__dict__.keys() + list(self._computedkeys) > > def values(self): > return self.__dict__.values() \ > + [getattr(self, key) for key in self._computedkeys] > > def items(self): > return zip(self.keys(), self.values()) > > def __iter__(self): > for k in self.keys(): > yield k > raise StopIteration > > def __contains__(self, key): > return key in self.keys() > > def __repr__(self): > return repr(dict(self.items()))
Thanks a lot for your help. I think what you have written is much better than what I could have come up with on my own. I guess I just need more experience. Thanks, Jeremy -- http://mail.python.org/mailman/listinfo/python-list