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

Reply via email to