Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #93108 > unrolled thread
| Started by | fl <rxjwg98@gmail.com> |
|---|---|
| First post | 2015-06-24 16:52 -0700 |
| Last post | 2015-06-25 10:16 +1000 |
| Articles | 2 — 2 participants |
Back to article view | Back to comp.lang.python
Could you explain this rebinding (or some other action) on "nums = nums"? fl <rxjwg98@gmail.com> - 2015-06-24 16:52 -0700
Re: Could you explain this rebinding (or some other action) on "nums = nums"? Chris Angelico <rosuav@gmail.com> - 2015-06-25 10:16 +1000
| From | fl <rxjwg98@gmail.com> |
|---|---|
| Date | 2015-06-24 16:52 -0700 |
| Subject | Could you explain this rebinding (or some other action) on "nums = nums"? |
| Message-ID | <94c2e42e-1e5f-40cf-9259-26035e277bf3@googlegroups.com> |
Hi,
I read a blog written by Ned and find it is very interesting, but I am still
unclear it in some parts. In the following example, I am almost lost at the
last line:
nums = num
Could anyone explain it in a more detail to me?
Thanks,
.......................
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.
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-06-25 10:16 +1000 |
| Message-ID | <mailman.37.1435191416.3674.python-list@python.org> |
| In reply to | #93108 |
On Thu, Jun 25, 2015 at 9:52 AM, fl <rxjwg98@gmail.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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web