Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Instances' __setitem__ methods

Reply
Thread Tools

Instances' __setitem__ methods

 
 
Spencer Pearson
Guest
Posts: n/a
 
      06-21-2011
I was recently trying to implement a dict-like object which would do
some fancy stuff when it was modified, and found that overriding the
__setitem__ method of an instance did not act the way I expected. The
help documentation (from help(dict.__setitem__)) claims that
"d.__setitem__(k,v)" is equivalent to "d[k]=v", but I've produced this
code that, on Python 2.6, acts differently in the two cases.

def print_args( key, value ):
print "print_args called: key = %s, value = %s" %(key,value)

class MyDict( dict ):
def __init__( self ):
dict.__init__( self )
self.__setitem__ = print_args

def __setitem__( self, key, value ):
print "ModelDict.__setitem__ called"
dict.__setitem__( self, key, value )

d = MyDict()

print "d.__setitem__(0,1):",
d.__setitem__(0,1)

print "d[0]=1:",
d[0]=1


I would expect the two setitems to both call print_args, but that's
not what happens. In the first case, it calls print_args, but in the
second case, the __setitem__ declared in MyDict is called instead.

The documentation at http://docs.python.org/reference/dat...l#specialnames
says that for new-style classes, "x[i]" is equivalent to
"type(x).__getitem__(x, i)". I assume that "x[i]=y" has similarly been
changed to be equivalent to "type(x).__setitem__(x, i, y)", since that
would produce the results that I'm getting. Is the help documentation
for dict.__setitem__ just outdated, or am I missing some subtlety
here?

Also: when I say "d.f(*args)", am I correct in thinking that d checks
to see if it has an instance attribute called "f", and if it does,
calls f(*args); and if it doesn't, checks whether its parent class
(and then its grandparent, and so on) has a class attribute called
"f", and if it does, calls f(x, *args)?
 
Reply With Quote
 
 
 
 
Ethan Furman
Guest
Posts: n/a
 
      06-21-2011
Spencer Pearson wrote:
> I was recently trying to implement a dict-like object which would do
> some fancy stuff when it was modified, and found that overriding the
> __setitem__ method of an instance did not act the way I expected.


The __magic__ methods are only looked up on the class, never the instance.

~Ethan~
 
Reply With Quote
 
 
 
 
Chris Rebert
Guest
Posts: n/a
 
      06-21-2011
On Mon, Jun 20, 2011 at 6:42 PM, Spencer Pearson
<(E-Mail Removed)> wrote:
> I was recently trying to implement a dict-like object which would do
> some fancy stuff when it was modified, and found that overriding the
> __setitem__ method of an instance did not act the way I expected. The
> help documentation (from help(dict.__setitem__)) claims that
> "d.__setitem__(k,v)" is equivalent to "d[k]=v", but I've produced this
> code that, on Python 2.6, acts differently in the two cases.


Technically, the strict equivalence is only one-way, as you've shown;
but one generally avoids calling the __magic__ methods directly, so
this subtle distinction is seldom used intentionally.

<snip>
> I would expect the two setitems to both call print_args, but that's
> not what happens. In the first case, it calls print_args, but in the
> second case, the __setitem__ declared in MyDict is called instead.
>
> The documentation at http://docs.python.org/reference/dat...l#specialnames
> says that for new-style classes, "x[i]" is equivalent to
> "type(x).__getitem__(x, i)". I assume that "x[i]=y" has similarly been
> changed to be equivalent to "type(x).__setitem__(x, i, y)", since that
> would produce the results that I'm getting. Is the help documentation
> for dict.__setitem__ just outdated, or am I missing some subtlety
> here?


The sentence of the docs in question begins with "For instance,";
hence, __setitem__ is just the arbitrarily-chosen example used in this
part of the docs. But the point applies equally to all the special
methods. See the very last section of the same webpage:
http://docs.python.org/reference/dat...-style-classes

> Also: when I say "d.f(*args)", am I correct in thinking that d checks
> to see if it has an instance attribute called "f", and if it does,
> calls f(*args); and if it doesn't, checks whether its parent class
> (and then its grandparent, and so on) has a class attribute called
> "f", and if it does, calls f(x, *args)?


See the first paragraph under the "Classes" entry on
http://docs.python.org/reference/dat...lues-and-types
for perfect accuracy.

Cheers,
Chris
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
'super' object has no attribute '__setitem__' luvspython Python 2 08-19-2011 02:07 AM
How can I use __setitem__ method of dict object? jeremito Python 12 02-07-2007 09:08 PM
str and __setitem__ Tor Erik Soenvisen Python 3 01-25-2007 11:06 AM
Inconsistency in dictionary behaviour: dict(dict) not calling __setitem__ Almad Python 8 12-14-2006 07:37 PM
Setdefault bypasses __setitem__ Ron Garret Python 9 10-14-2005 06:01 AM



Advertisments