Setdefault bypasses __setitem__

Peter Otten __peter__ at web.de
Thu Oct 13 04:12:49 EDT 2005


Diez B. Roggisch wrote:

> Ron Garret wrote:
>> Is this a bug or a feature?
>> 
>> class mydict(dict):
>>    def __setitem__(self, key, val):
>>      print 'foo'
>>      dict.__setitem__(self, key, val)
>> 
>> 
>>>>>d=mydict()
>>>>>d[1]=2
>> 
>> foo
>> 
>>>>>d.setdefault(2,3)
> 
> 
> 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.

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




More information about the Python-list mailing list