On 17Aug2017 02:49, Mok-Kong Shen <mok-kong.s...@t-online.de> wrote:
I don't yet understand. Why (by which rule of the language reference)
should "alist=[30,60,90]" mean discarding the name's reference to the
[1,2,3] list?

Section 7.2: Simple statements: Assignment Statements.

It says:

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

So this:

 alist=[30,60,90]

"evaluates the expression list" (that is the [30,60,90]) and assigns it.

So this creates a new list object [30,60,90]. This is independent of whatever is/was in "alist". Then the reference to that is assigned to the name "alist". Since a name references to a single object, necessarily the reference to what "alist" previously refered is discarded.

So before this statement, both "ss" and "alist" referered to the list [1,2,3]. After the statement "ss" has not been changed, and still refers to the [1,2,3] list. But "alist" now points to the new list which was created by the right hand side of the assignment statement i.e. the new [30,60,90] list.

You might try inserting some print statements in your code.
 print("ss = %s:%r, alist = %s:%r" % (id(ss), ss, id(alist), alist))

after every statement in your code to see these changes. The id() function returns Python's internal object id for each existing object - this is unique at any given time. If two names refer to the same object, the same id will be printed. So this will let you see directly when the names start pointing at different objects.

You can also go:

 print("alist[0] = %s:%r" % (id(alist[0]), alist[0]))

to see the internal things within lists and so forth.

What I conjecture is that in test2 the assignment
"alist[0], ..." can only have a proper meaning according to the syntacs
of Python if alist is meant to be the global alist.

There is no "global alist".

But then, since
now the name alist is known to be global, why then in the next line of
test2 the name is suddenly interpreted to be local?

There are two reasons for this. Firstly, "alist" is a function parameter. That is a local name, always. Also, every python function definition is inspected for assignment statements. Any assignment statement "x = ..." causes the name "x" to be a local variable. This is important, because it provided _reliable_ and predictable behaviour.

(Which rule of
the language reference says that?) That's what I currently continue to
wonder.

4.2. Naming and Binding.

4.2.1 starts "Names refer to objects. Names are introduced by name binding operations. The following constructs bind names: formal parameters to functions, ...". So a function parameter is a name binding.

Then "if a name is bound in a block, it is a local variable of that block, unless declared as nonlocal or global." ("nonlocal" and "global" are explicit statements.) So a function parameter, which is a binding, causes that name to be local to the function.

Regarding the inspection side of things to which i alluded to earlier, under "4.2.2. Resolution of names" it says "If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations."

Cheers,
Cameron Simpson <c...@cskk.id.au> (formerly c...@zip.com.au)
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to