
01.03.19 06:21, Guido van Rossum пише:
On Wed, Feb 27, 2019 at 11:18 PM Serhiy Storchaka <storchaka@gmail.com <mailto:storchaka@gmail.com>> wrote: Counter uses + for a *different* behavior!
>>> Counter(a=2) + Counter(a=3) Counter({'a': 5})
Well, you can see this as a special case. The proposed + operator on Mappings returns a new Mapping whose keys are the union of the keys of the two arguments; the value is the single value for a key that occurs in only one of the arguments, and *somehow* combined for a key that's in both. The way of combining keys is up to the type of Mapping. For dict, the second value wins (not so different as {'a': 1, 'a': 2}, which becomes {'a': 2}). But for other Mappings, the combination can be done differently -- and Counter chooses to add the two values.
Currently Counter += dict works and Counter + dict is an error. With this change Counter + dict will return a value, but it will be different from the result of the += operator. Also, if the custom dict subclass implemented the plus operator with different semantic which supports the addition with a dict, this change will break it, because dict + CustomDict will call dict.__add__ instead of CustomDict.__radd__. Adding support of new operators to builting types is dangerous.
I do not understand why we discuss a new syntax for dict merging if we already have a syntax for dict merging: {**d1, **d2} (which works with *all* mappings). Is not this contradicts the Zen?
But (as someone else pointed out) {**d1, **d2} always returns a dict, not the type of d1 and d2.
And this saves us from the hard problem of creating a mapping of the same type. Note that reference implementations discussed above make d1 + d2 always returning a dict. dict.copy() returns a dict.
Also, I'm sorry for PEP 448, but even if you know about **d in simpler contexts, if you were to ask a typical Python user how to combine two dicts into a new one, I doubt many people would think of {**d1, **d2}. I know I myself had forgotten about it when this thread started! If you were to ask a newbie who has learned a few things (e.g. sequence concatenation) they would much more likely guess d1+d2.
Perhaps the better solution is to update the documentation.