[Python-Dev] defaultdict proposal round three

Guido van Rossum guido at python.org
Mon Feb 20 14:41:43 CET 2006

I'm withdrawing the last proposal. I'm not convinced by the argument
that __contains__ should always return True (perhaps it should also
insert the value?), nor by the complaint that a holy invariant would
be violated (so what?).

But the amount of discussion and the number of different viewpoints
present makes it clear that the feature as I last proposed would be
forever divisive.

I see two alternatives. These will cause a different kind of
philosophical discussion; so be it. I'll describe them relative to the
last proposal; for those who wisely skipped the last thread, here's a
link to the proposal:

Alternative A: add a new method to the dict type with the semantics of
__getattr__ from the last proposal, using default_factory if not None
(except on_missing is inlined). This avoids the discussion about
broken invariants, but one could argue that it adds to an already
overly broad API.

Alternative B: provide a dict subclass that implements the __getattr__
semantics from the last proposal. It could be an unrelated type for
all I care, but I do care about implementation inheritance since it
should perform just as well as an unmodified dict object, and that's
hard to do without sharing implementation (copying would be worse).

Parting shots:

- Even if the default_factory were passed to the constructor, it still
ought to be a writable attribute so it can be introspected and
modified. A defaultdict that can't change its default factory after
its creation is less useful.

- It would be unwise to have a default value that would be called if
it was callable: what if I wanted the default to be a class instance
that happens to have a __call__ method for unrelated reasons?
Callability is an elusive propperty; APIs should not attempt to
dynamically decide whether an argument is callable or not.

- A third alternative would be to have a new method that takes an
explicit defaut factory argument. This differs from setdefault() only
in the type of the second argument. I'm not keen on this; the original
use case came from an example where the readability of

  d.setdefault(key, []).append(value)

was questioned, and I'm not sure that

  d.something(key, list).append(value)

is any more readable. IOW I like (and I believe few have questioned)
associating the default factory with the dict object instead of with
the call site.

Let the third round of the games begin!

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list