Inconsistency in dictionary behaviour: dict(dict) not calling __setitem__
Mitja Trampus
nun at example.com
Tue Dec 12 17:33:41 EST 2006
Fredrik Lundh wrote:
> Almad wrote:
>
>> However, when constructing dictionary with dictionary in constructor
>> like d = RegisterMap({'k':'v'}), __setitem__ is not called
>
> why should it do that? dict() is a concrete implementation, not a
> template class for the creation of dict-like objects.
I think what was unexpected for the OP is that dict.__init__
does not use __setitem__ to create its internal structures.
This is independent of dict being a concrete implementation
or not:
>>> class H:
... def __init__(self): self.hello()
... def hello(self): print 'oi oi'
>>> class K(H):
... def hello(self): print 'hello'
>>> K()
hello
<__main__.K instance at 0x00AC9878>
At least, I know it surprised me when I first met this
behavior. Or is my reasoning incorrect?
Further to the OP: This is due to optimizations -
initialization is much faster if it's done by modifying
dict's internal state directly and thus without calling a
(possibly custom-made) method for each item to be inserted.
What I find an even nastier surprise is that dict.update
behaves this way as well:
>>> class D(dict):
... def __setitem__(self,k,v):
... print 'setting',k,'to',v
... dict.__setitem__(self,k,v)
>>> d=D({1:'a', 2:int})
# No output here - OK, half-expected
>>> d.update({3:'s',6:23})
# No output here, either...
The docstring is, at best, misguiding on this particular point:
>>> print d.update.__doc__
D.update(E, **F) -> None. Update D from E and F: for k in
E: D[k] = E[k]
(if E has keys else: for (k, v) in E: D[k] = v) then: for k
in F: D[k] = F[k]
It's not a big issue, but an almost sure one-time surprise
for everyone, I suppose...
More information about the Python-list
mailing list