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