nonlocal fails ?

Richard Damon Richard at Damon-Family.org
Fri Nov 15 10:48:58 EST 2019


On 11/15/19 6:56 AM, R.Wieser wrote:
> There are quite a number of languages where /every/ type of argument 
> (including values) can be transfered "by reference".  Though some default to 
> "by value", where others default to "by reference".

It seems you are stuck in a programming model different than what Python
provides, In a very real sense, the terms call "By Reference" and "By
Value" don't apply to Python. Those concepts presume that a variable
name represents a bucket of bytes that holds some value, and call by
value copies those bytes into a new variable for the subroutine, and
call by Reference creates a pointer value back to original value, and
all uses of that parameter work indirect that pointer.

That is NOT how Python works. In Python, in effect, every name in your
code is just a reference which points to some object (This is called
binding). Multiple names can point to the same object (or no names, at
which point the object is subject to being garbage collected). Names
themselves aren't objects, so you can't really make one name refer to
another, only to the same object that the other one does. (In actuality,
these collections of names are implemented basically in a Dictionary, so
using this sort of implementation details you can sort of get that
result, but I don't think that is defined to work in the language).

In the more classical languages, to draw a model of the variables you
have in memory, you take a big sheet of paper, put down each variable
name, and next to it a box where you put what value is stored in the
variable, and that value is intimately associated with that variable
name. You might have some objects being or containing
pointers/references and in that case you can represent it by an arrow
from the box representing the pointer to the object it is pointing to.
There may be some object that are created without a name (like on the
heap), but many of the objects are directly tied to a name.

In Python you do this differently. On one side of your paper, you put
your variable names, and on the other (perhaps a larger side) all the
values/objects you are working with. Each name gets an arrow to an
object to show what object it is currently bound to. Objects store the
values they hold, and some, like collections) also have arrows to other
objects they reference. An arrow always points to an object, never to a
name on the left side.

An assignment just changes what object a reference points to. If it is a
'top level' name being assigned to (as opposed to referring to a member
of an object or element of a collection), that is changing one of the
names on the left side of the page.

This difference in value model means you have to think about things
differently, and in a very real sense makes the terms 'by value' and 'by
reference' not applicable. You don't get values 'By Value', because you
didn't get a copy of the object reference, so if you mutate it, the
caller sees the change, but also it isn't by reference, as you can't
rebind the callers reference to point to a different object. This isn't
'Wrong' just 'Different'.

It takes some getting used to a different model, and I think it helps to
accept that it is different rather than trying to keep trying to
translate how Python does things into how some other language does it,
as the latter make you focus on the things it can't do, not the things
it can.

-- 
Richard Damon



More information about the Python-list mailing list