On 21Jan2020 17:40, Stephen Tucker <stephen_tuc...@sil.org> wrote:
I am sure this has been answered many times before, but I need to ask
it
again.
Given that the following is valid Python 2.7.10 (when keyboarded into Idle):
mytup = ("q", "w", "e")
id(mytup)
mytup = mytup [:2]
id(mytup)
and even that the first id(mytup) returns the same address as the second
one,
Really? Not here:
[~]fleet*> python2.7
Python 2.7.16 (default, Apr 1 2019, 15:01:04)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> mytup = ("q", "w", "e")
>>> id(mytup)
4541315104
>>> mytup = mytup [:2]
>>> id(mytup)
4542334880
>>>
I am left wondering exactly what immutability is.
Immutability generally means that the direct contents of the object may
not be changed:
>>> mytup = (1,2,3)
>>> mytup[1]
2
>>> mytup[1] = 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
It doesn't say anything about the contents of the internal objects:
>>> mytup = (1, [2, 3], (4, 5))
>>> mytup[0] = 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> mytupl[1] = [7, 8]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'mytupl' is not defined
>>> mytup[1].append(10)
>>> mytup
(1, [2, 3, 10], (4, 5))
>>> mytup[2].append(11)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
So you can see that I may modify the content of the list at mytup[1].
However, I can't replace mytup[1] with another list, because mytup
_itself_ is immutable.
I am left concluding that mytup is not actually a tuple (even though type
(mytup) tells me that it is).
My only explanation is that mytup is, actually, a pointer to a tuple; the
pointer can't change, but the contents of that pointer (or the data to
which the pointer points) can change.
Ah. You're confusing the variable "mytup" with the object which it
references.
"mytup" is a Python variable, which is reference to some object (a lot
like a pointer conceptually, but not a pointer - a "pointer" is a memory
address - so say "reference" and not "pointer" and people here will be
happier).
Here, "mytup" refers to a tuple object. "type(mytup)" accesses that
object and tells you its type (a tuple). You can change "mytup":
mytup = [1, 2, 3]
which causes it to refer to a different object. By you can't change the
direct references in the original tuple object (eg mytup[1]).
That said, if I then type
mytup = mytup + ("r", "t")
id(mytup)
I find that this third id call returns a different address from the one
returned by the first two.
A newtuple has been created, and "mytup" and been changed to refer to
the new object.
Somehow, it seems, tuples can be reduced in length (from the far end)
(which is not what I was expecting), but they cannot be extended (which I
can understand).
No, you're seeing new tuples of different lengths. "mytup" is just being
switched around by the assignment statement to refer to the new tuples.
If you're familiar with "pointers" in C-like languages, where a pointer
variable holds the address of something, think of Python variables as
somewhat like those. They're a little more complex but the behaviour is
similar. Here "mytup" is like a pointer variable in C, and the tuple is
the "something" to which it points. The tuple is immutable, not the
pointer.
Why do we distinguish between "pointer" and "reference", particularly
which CPython does a lotof this internally with C pointers (id() in
CPython returns an address as it happens)? Because there are multiple
implementations of Python, and they needn't use C-like pointers
internally. Imagine the id() was an index into some table-of-objects and
that the table itself held pointers, eg so that the object storage
itself could be moved around.
So Python variables are references. The variables themselves are not
immutable.
Cheers,
Cameron Simpson <c...@cskk.id.au> (formerly c...@zip.com.au)
Draw little boxes with arrows. It helps. - Michael J. Eager
--
https://mail.python.org/mailman/listinfo/python-list