On Feb 6, 10:59 am, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> wrote: > On 6 fév, 16:23, "jeremito" <[EMAIL PROTECTED]> wrote: > > > > > Please excuse me if this is obvious to others, but I can't figure it > > out. I am subclassing dict, but want to prevent direct changing of > > some key/value pairs. For this I thought I should override the > > __setitem__ method as such: > > > class xs(dict): > > """ > > XS is a container object to hold information about cross sections. > > """ > > > def __new__(cls, xS=1.0, xF=1.0, xG=1.0, nu=1.0, debug=0): > > """ > > """ > > x = {} > > x['xS'] = xS > > x['xF'] = xF > > x['nu'] = nu > > x['xG'] = xG > > x['xA'] = x['xG'] + x['xF'] > > x['xT'] = x['xA'] + x['xS'] > > > return x > > replace this with: > def __init__(self, xS=1.0, xF=1.0, xG=1.0, nu=1.0, debug=0): > dict.__init__( > self, > xS=xS, > xF=xF, > xG=xG, > nu=nu, > xA=xG + xF, > xT=xG + xF + xS > ) > > > def __setitem__(self, key, value): > > """ > > I have overridden this method to prevent setting xT or xA > > outside the > > class. > > """ > > print "I am in __setitem__" > > if key == 'xT': > > raise AttributeError( > > "Can't change xT. Please change, xF, xS, or xG" > ) > dict.__setitem__(self, key, value) > > > 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? 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? > > > Example: > > Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) > > [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin > > Type "help", "copyright", "credits" or "license" for more information.>>> > > import xs > > >>> cs = xs.xs() > > >>> cs > > > {'xA': 2.0, 'xF': 1.0, 'xG': 1.0, 'xS': 1.0, 'nu': 1.0, 'xT': 3.0}>>> > > cs['xT'] = 3.1415 > > >>> cs > > > {'xA': 2.0, 'xF': 1.0, 'xG': 1.0, 'xS': 1.0, 'nu': 1.0, 'xT': > > 3.1415000000000002} > > > 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. > 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. > > My 2 cents... Thanks again, Jeremy -- http://mail.python.org/mailman/listinfo/python-list