[Python-Dev] defaultdict proposal round three

Alex Martelli aleaxit at gmail.com
Mon Feb 20 20:09:48 CET 2006


On Feb 20, 2006, at 8:35 AM, Raymond Hettinger wrote:

> [GvR]
>> I'm not convinced by the argument
>> that __contains__ should always return True
>
> Me either.  I cannot think of a more useless behavior or one more  
> likely to have
> unexpected consequences.  Besides, as Josiah pointed out, it is  
> much easier for
> a subclass override to substitute always True return values than  
> vice-versa.

Agreed on all counts.

> I prefer this approach over subclassing.  The mental load from an  
> additional
> method is less than the load from a separate type (even a  
> subclass).   Also,
> avoidance of invariant issues is a big plus.  Besides, if this allows
> setdefault() to be deprecated, it becomes an all-around win.

I'd love to remove setdefault in 3.0 -- but I don't think it can be  
done before that: default_factory won't cover the occasional use  
cases where setdefault is called with different defaults at different  
locations, and, rare as those cases may be, any 2.* should not break  
any existing code that uses that approach.

>> - 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.
>
> Right!  My preference is to have default_factory not passed to the  
> constructor,
> so we are left with just one way to do it.  But that is a nit.

No big deal either way, but I see "passing the default factory to the  
ctor" as the "one obvious way to do it", so I'd rather have it (be it  
with a subclass or a classmethod-alternate constructor). I won't weep  
bitter tears if this drops out, though.


>> - 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.
>
> That makes sense, though it seems over-the-top to need a zero- 
> factory for a
> multiset.

But int is a convenient zero-factory.

>
> An alternative is to have two possible attributes:
>   d.default_factory = list
> or
>   d.default_value = 0
> with an exception being raised when both are defined (the test is  
> done when the
> attribute is created, not when the lookup is performed).

I see default_value as a way to get exactly the same beginner's error  
we already have with function defaults: a mutable object will not  
work as beginners expect, and we can confidently predict (based on  
the function defaults case) that python-list and python-help and  
python-tutor and a bazillion other venues will see an unending stream  
of confused beginners (in addition to those confused by mutable  
objects as default values for function arguments, but those can't be  
avoided). I presume you consider the "one obvious way" is to use  
default_value for immutables and default_factory for mutables, but  
based on a lot of experience teaching Python I feel certain that this  
won't be obvious to many, MANY users (and not just non-Dutch ones,  
either).


Alex



More information about the Python-Dev mailing list