The meaning of "=" (Was: tough-to-explain Python)
no.email at please.post
Wed Jul 8 18:38:48 CEST 2009
In <h32fon$264$1 at panix3.panix.com> aahz at pythoncraft.com (Aahz) writes:
>In article <h32eoh$ql8$1 at reader1.panix.com>, kj <no.email at please.post> wrote:
>>OK, so, scratching from my original post the case
>><identifier>.<identifier> = <expression>
>>(as being a special case of <identifier> = <expression>), still,
>>to the extent that I understand your post, the "=" in
>> x = 1
>>means something fundamentally different (in terms of Python's
>>underlying implementation) from the "=" in
>> y = 1
No??? Just when I thought I finally understood all this!
>What's different is not the ``=`` but the construction of the
>assignment target before ``=`` gets executed.
Hmm. OK, I went to the link you posted in your other message
and I find this (my emphasis):
Assignment of an object to a single target is recursively defined as follows.
* If the target is an identifier (name):
o If the name does not occur in a global statement in
the current code block: the name is bound to the object
in the current local namespace.
o Otherwise: the name is bound to the object in the
current global namespace.
The name is rebound if it was already bound. This may cause
the reference count for the object previously bound to the
name to reach zero, causing the object to be deallocated and
its destructor (if it has one) to be called.
* If the target is a target list enclosed in parentheses or in
square brackets... (I'LL IGNORE THIS FOR NOW)
* If the target is an attribute reference: The primary expression
in the reference is evaluated. It should yield an object with
assignable attributes; if this is not the case, TypeError is
raised. That object is then asked to assign the assigned
object to the given attribute; if it cannot perform the
assignment, it raises an exception (usually but not necessarily
* If the target is a subscription: The primary expression in
the reference is evaluated. It should yield either a mutable
sequence object (such as a list) or a mapping object (such
as a dictionary). Next, the subscript expression is evaluated.
If the primary is a mutable sequence object (such as a
list),... [CONDITIONS ON THE INDEX EXPRESSION OMITTED]...
the sequence is asked to assign the assigned object to its
item with that index....
If the primary is a mapping object (such as a dictionary),...
[CONDITIONS ON THE SUBSCRIPT EXPRESSION OMITTED]... the
mapping is then asked to create a key/datum pair which maps
the subscript to the assigned object.
* If the target is a slicing: [INDEX STUFF OMITTED]... the
sequence object is asked to replace the slice with the items
of the assigned sequence...
OK, I originally interpreted what Lundh wrote in his two articles
that the "binding" described at the very beginning (i.e. when the
target is an identifier), which I take to make an entry or modify
such an entry in a namespace, is a *categorically different*
operation from the remaining operations underlined above.
I interpreted Paul Boddie's correction in his response to me as
saying that the "assignment" mentioned for the case when the target
is an attribute reference is actually a special case of the
"assignment" to simple identifiers (i.e. it also means "binding").
But that still leaves all the other "assignments" (or the like)
underlined above. I don't think that the full definitions of these
remaining cases are covered by the same rule, even though the rule
is described as "recursive." I think that the writer has something
else in mind, and in particular, something *other* than binding,
but the author remains vague on exactly what this means.
Clearly, both Lundh and the documentation draw some distinction
between "binding" and some other forms of "assignment" (which remain
ill-defined throughout). This distinction is what I was referring
to when I said that "=" means different things in different contexts.
More information about the Python-list