On 2015-12-01 02:14, fl wrote:
On Wednesday, June 24, 2015 at 8:17:08 PM UTC-4, Chris Angelico wrote:
On Thu, Jun 25, 2015 at 9:52 AM, fl <rxjgmail.com> wrote:
> The reason is that list implements __iadd__ like this (except in C, not 
Python):
>
> class List:
>     def __iadd__(self, other):
>         self.extend(other)
>         return self
> When you execute "nums += more", you're getting the same effect as:
>
> nums = nums.__iadd__(more)
> which, because of the implementation of __iadd__, acts like this:
>
> nums.extend(more)
> nums = nums
> So there is a rebinding operation here, but first, there's a mutating 
operation, and the rebinding operation is a no-op.

It's not a complete no-op, as can be demonstrated if you use something
other than a simple name:

>>> tup = ("spam", [1, 2, 3], "ham")
>>> tup[1]
[1, 2, 3]
>>> tup[1].extend([4,5])
>>> tup[1] = tup[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> tup
('spam', [1, 2, 3, 4, 5], 'ham')
>>> tup[1] += [6,7]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> tup
('spam', [1, 2, 3, 4, 5, 6, 7], 'ham')

The reason for the rebinding is that += can do two completely
different things: with mutable objects, like lists, it changes them in
place, but with immutables, it returns a new one:

>>> msg = "Hello"
>>> msg += ", world!"
>>> msg
'Hello, world!'

This didn't change the string "Hello", because you can't do that.
Instead, it rebound msg to "Hello, world!". For consistency, the +=
operator will *always* rebind, but in situations where that's not
necessary, it rebinds to the exact same object.

Does that answer the question?

ChrisA

I have revisit the past post. In the example code snippet:

type(tup[1])
Out[162]: list

'list' is mutable. Why does the following line have errors?
In practical Python code, error is not acceptable. Then, what purpose is
for the following code here to show?

Thanks,


tup[1] += [6,7]
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

When you write:

    x += y

Python tries to do:

    x = x.__iadd__(y)

If x doesn't have the "__iadd__" method, Python then tries to do:

    x = x.__add__(y)

The "__iadd__" method should mutate the object in-place and then return
itself.

Here's an example where it returns something else instead:

# Example

class Test:
    def __init__(self):
        self.string = ''

    def __iadd__(self, other):
        self.string += other
        return "Surprise!"

t = Test()
t += 'foo'
print(t)

# End of example

In the case of:

    tup[1] += [6, 7]

what it's trying to do is:

    tup[1] = tup[1].__iadd__([6, 7])

tup[1] refers to a list, and the __iadd__ method _does_ mutate it, but
then Python tries to put the result that the method returns into
tup[1]. That fails because tup itself is a tuple, which is immutable.

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to