
On Fri, Feb 13, 2015 at 5:19 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Chris Barker - NOAA Federal wrote:
But why does it work that way? Because it needs to work on immutable objects. If it didn't, then you wouldn't need the "assign back to the original name" step.
This doesn't make it wrong for in-place operators to work on immutable objects. There are two distinct use cases:
1) You want to update a mutable object in-place.
what I think this the "real" use case. ;-) 2) The LHS is a complex expression that you only want
to write out and evaluate once.
Can you give an example of this? how can put an expression in the right hand side? I seem to only get errors: In [23]: l1 Out[23]: [1] In [24]: l2 Out[24]: [2] In [25]: (l1 + l2) += [3] File "<ipython-input-25-b8781c271c74>", line 1 (l1 + l2) += [3] SyntaxError: can't assign to operator which makes sense -- the LHS is an expression that results in a list, but += is trying to assign to that object. HOw can there be anything other than a single object on the LHS? In fact, if this worked like I expect and want it to -- that Would work. but that fat hat we've mixed in-place operation with "shorthand for operation plus assignment" makes this a mess. There are ways that the tuple problem could be fixed, such as skipping the assignment if __iadd__ returns the same
object. But that would be a backwards-incompatible change, since there could be code that relies on the assignment always happening.
I wonder if there is are many real use cases of that -- do people really write: In [28]: try: ....: t[0] += [4] ....: except TypeError: ....: pass It seems making that change would let things not raise an error that would otherwise. Or, I suppose, the equivalent of that try:except could be build into augmented assignment..
If it's in-place for a mutable object, it needs to return self. But
the python standard practice is that methods that mutate objects shouldn't return self ( like list.sort() ) for instance.
The reason for that is to catch the mistake of using a mutating method when you meant to use a non-mutating one. That doesn't apply to __iadd__, because you don't usually call it yourself.
Sure -- but my point is that at least by convention, se keep "mutating an object" and "creating a new object" clearly distinct -- but not in this case. I'm pretty convinced, band my memory of the conversation when this was added, is that the was a case of some people wanting shorthand like: i += 1 and others wanted a way to express in-place operations conveniently: array += 1 And this was seen as a way to kill two birds with one stone -- and that has let to this confusing behavior. And BOTH are simply syntactic sugar: i += 1 ==> i = i+1 and array += 1 ==> np.add(array, 1, out=array) I would argue that the seconds is a major win, and the first only a minor win. ( and yes, I did right a bunch of ugly code that looks like the second line before augmented assignment existed.) But this is all mute -- the cast is well out of the bag on this. Though if we could clean it up a bit, that would be nice. -Chris
-- Greg
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov