Setdefault bypasses __setitem__

Discussion in 'Python' started by Ron Garret, Oct 13, 2005.

  1. Ron Garret

    Ron Garret Guest

    Is this a bug or a feature?

    class mydict(dict):
    def __setitem__(self, key, val):
    print 'foo'
    dict.__setitem__(self, key, val)

    Ron Garret, Oct 13, 2005
    1. Advertisements

  2. Feature. If it wouldn't bypass __setitem__, how exactly would you make a
    default-item? Using __setitem__ implies a key. So if setdefault
    was implemented as

    def setdefault(self, v):
    self["SOME_DEFAULT_KEY_NAME"] = v

    and later on one writes e.g. a HTML-page with a form input field named
    "SOME_DEFAULT_KEY_NAME" that gets stored in a dict - it would overwrite
    the default value.

    So it has to bypass __setitem__, as otherwise it can't distinguish
    between "real" and the default value - the latter one is not allowed to
    have a key that is in any imaginable way used by the user.

    Diez B. Roggisch, Oct 13, 2005
    1. Advertisements

  3. Ron Garret

    Peter Otten Guest

    The implementation is certainly a design decision. setdefault() could be
    implemented in terms of __set/getitem__() as

    def setdefault(self, key, value=None):
    return self[key]
    except KeyError:
    self[key] = value
    return self[key]

    I guess it's not done for performance reasons.

    Peter Otten, Oct 13, 2005
  4. The implementation is certainly a design decision. setdefault() could be
    Nope. What if you changed your default value? Then you'd have to update
    the whole dictionary - but without keeping track of the keys you placed
    the default value under that isn't possible. Which strikes me as
    more-than-marginal overhead - without any advantage (as using
    __setitem__ for the default value isn't something I consider being a
    missing feature...)

    Diez B. Roggisch, Oct 13, 2005
  5. Ron Garret

    Peter Otten Guest

    Are we talking about the same setdefault()?

    D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D

    There is no per-instance default value just on per call:

    I'm sure there is a misunderstanding in our conversation, I'm just not able
    to nail it...

    Peter Otten, Oct 13, 2005
  6. note that it might be spelled "setdefault", but it should be pronounced
    "get or set".

    Fredrik Lundh, Oct 13, 2005
  7. Ron Garret

    Duncan Booth Guest

    if setdefault was implemented that way then all current uses of setdefault
    would throw an exception.

    setdefault takes *three* parameters: self, key, value. Once you include the
    key parameter your entire argument implodes.
    Duncan Booth, Oct 13, 2005
  8. Oh. You're right. I was somehow under the impression that setdefault is
    per-instance, so that I can avoid

    d.get(key, default)

    and write


    instead, for all keys, and get no more KeyErrors. But then you are
    right of course.


    Diez B. Roggisch, Oct 13, 2005
  9. Yup. It does implode, leaving me thunderstruck because of my dumbness.

    I rarely find things in python strange or named incorrectly, but this is
    IMHO such a case - setdefault led me to think that using it would set a
    default value to return for _future_ lookups of non-existant keys. That
    semantics is known in e.g. ruby or java.

    I think a better name would be getdefault, or even get_setdefault - in
    oppposition to the get(key, d) form.

    But now that this became clear to me... I guess I can live with the name :)

    Diez B. Roggisch, Oct 14, 2005
  10. as long as you pronounce it correctly (see my earlier post).

    Fredrik Lundh, Oct 14, 2005
    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.