dict.setdefault() (Patch#101102) (was: Re: [Python-Dev] Re: A small proposed change to dictionaries' "get" method...)

Guido van Rossum guido@beopen.com
Mon, 07 Aug 2000 09:11:52 -0500


> Guido:
> >     >> dict.default('hello', []).append('hello')
> 
> Greg Ewing <greg@cosc.canterbury.ac.nz>:
> >     GE> Is this new method going to apply to dictionaries only,
> >     GE> or is it to be considered part of the standard mapping
> >     GE> interface?
>  
> Barry A. Warsaw:
> > I think we've settled on setdefault(), which is more descriptive, even
> > if it's a little longer.  I have posted SF patch #101102 which adds
> > setdefault() to both the dictionary object and UserDict (along with
> > the requisite test suite and doco changes).

PF:
> This didn't answer the question raised by Greg Ewing.  AFAI have seen,
> the patch doesn't touch 'dbm', 'shelve' and so on.  So from the patch
> the answer is "applies to dictionaries only".

I replied to Greg Ewing already: it's not part of the required mapping
protocol.

> What is with the other external mapping types already in the core,
> like 'dbm', 'shelve' and so on?
> 
> If the patch doesn't add this new method to these other mapping types, 
> this fact should at least be documented similar to the methods 'items()' 
> and 'values' that are already unimplemented in 'dbm':
>  """Dbm objects behave like mappings (dictionaries), except that 
>     keys and values are always strings.  Printing a dbm object 
>     doesn't print the keys and values, and the items() and values() 
>     methods are not supported."""

Good point.

> I'm still -1 on the name:  Nobody would expect, that a method 
> called 'setdefault()' will actually return something useful.  May be 
> it would be better to invent an absolutely obfuscuated new name, so 
> that everybody is forced to actually *READ* the documentation of this 
> method or nobody will guess, what it is supposed to do or even
> worse: how to make clever use of it.

I don't get your point.  Since when is it a requirement for a method
to convey its full meaning by just its name?  As long as the name
doesn't intuitively contradict the actual meaning it should be fine.

If you read code that does:

	dict.setdefault('key', [])
	dict['key'].append('bar')

you will have no problem understanding this.  There's no need for the
reader to know that this is suboptimal.  (Of course, if you're an
experienced Python user doing a code review, you might know that.  But
it's not needed to understand what goes on.)

Likewise, if you read code like this:

	dict.setdefault('key', []).append('bar')

it doesn't seem hard to guess what it does (under the assumption that
you already know the program works).  After all, there are at most
three things that setdefault() could *possibly* return:

1. None		-- but then the append() would't work

2. dict		-- but append() is not a dict method so wouldn't work either

3. dict['key']	-- this is the only one that makes sense

> At least it would be a lot more likely, that someone becomes curious, 
> what a method called 'grezelbatz()' is suppoed to do, than that someone
> will actually lookup the documentation of a method called 'setdefault()'.

Bogus.  This would argue that we should give all methods obscure names.

> If the average Python programmer would ever start to use this method 
> at all, then I believe it is very likely that we will see him/her
> coding:
> 	dict.setdefault('key', [])
> 	dict['key'].append('bar')

And I have no problem with that.  It's still less writing than the
currently common idioms to deal with this!

> So I'm also still -1 on the concept.  I'm +0 on Gregs proposal, that
> it would be better to make this a builtin function, that can be applied
> to all mapping types.

Yes, and let's also make values(), items(), has_key() and get()
builtins instead of methods.  Come on!  Python is an OO language.

> Maybe it would be even better to delay this until in Python 3000
> builtin types may have become real classes, so that this method may
> be inherited by all mapping types from an abstract mapping base class.

Sure, but that's not an argument for not adding it to the dictionary
type today!

--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)