Instances' __setitem__ methods

Discussion in 'Python' started by Spencer Pearson, Jun 21, 2011.

  1. 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):",

    print "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
    says that for new-style classes, "x" is equivalent to
    "type(x).__getitem__(x, i)". I assume that "x=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

    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)?
    Spencer Pearson, Jun 21, 2011
    1. Advertisements

  2. Spencer Pearson

    Ethan Furman Guest

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

    Ethan Furman, Jun 21, 2011
    1. Advertisements

  3. Spencer Pearson

    Chris Rebert Guest

    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.

    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:
    See the first paragraph under the "Classes" entry on
    for perfect accuracy.

    Chris Rebert, Jun 21, 2011
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.