How can I use __setitem__ method of dict object?
jeremito
jeremit0 at gmail.com
Tue Feb 6 11:42:55 EST 2007
On Feb 6, 10:59 am, "bruno.desthuilli... at gmail.com"
<bruno.desthuilli... at gmail.com> wrote:
> On 6 fév, 16:23, "jeremito" <jerem... at gmail.com> 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
More information about the Python-list
mailing list