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)
    3

    rg
     
    Ron Garret, Oct 13, 2005
    #1
    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
     
    Diez B. Roggisch, Oct 13, 2005
    #2
    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):
    try:
    return self[key]
    except KeyError:
    self[key] = value
    return self[key]

    I guess it's not done for performance reasons.

    Peter
     
    Peter Otten, Oct 13, 2005
    #3
  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
     
    Diez B. Roggisch, Oct 13, 2005
    #4
  5. Ron Garret

    Peter Otten Guest

    Are we talking about the same setdefault()?

    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:
    1

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

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

    </F>
     
    Fredrik Lundh, Oct 13, 2005
    #6
  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
    #7
  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

    d[key]

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

    Regards,

    Diez
     
    Diez B. Roggisch, Oct 13, 2005
    #8
  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
     
    Diez B. Roggisch, Oct 14, 2005
    #9
  10. as long as you pronounce it correctly (see my earlier post).

    </F>
     
    Fredrik Lundh, Oct 14, 2005
    #10
    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.