6.3 Assignment statements
Assignment statements
are used to (re)bind names to values and to modify attributes or items of mutable
objects:
-
(See section 5.3 for the syntax definitions
for the last three symbols.)
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.
Assignment is defined recursively depending on the form of the target (list). When a
target is part of a mutable object (an attribute reference, subscription or slicing), the
mutable object must ultimately perform the assignment and decide about its validity, and
may raise an exception if the assignment is unacceptable. The rules observed by various
types and the exceptions raised are given with the definition of the object types (see
section 3.2).
Assignment of an object to a target list is recursively defined as follows.
- If the target list is a single target: The object is assigned to that target.
- If the target list is a comma-separated list of targets: The object must be a
sequence with the same number of items as there are targets in the target list, and
the items are assigned, from left to right, to the corresponding targets. (This rule
is relaxed as of Python 1.5; in earlier versions, the object had to be a tuple. Since
strings are sequences, an assignment like "a, b = "xy""
is now legal as long as the string has the right length.)
Assignment of an object to a single target is recursively defined as follows.
- If the target is an identifier (name):
- 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.
- 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: The
object must be a sequence with the same number of items as there are targets in the
target list, and its items are assigned, from left to right, to the corresponding
targets.
- 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 AttributeError).
- If the target is a subscription: The primary expression in the reference is
evaluated. It should yield either a mutable sequence object (e.g., a list) or a
mapping object (e.g., a dictionary). Next, the subscript expression is evaluated.
If the primary is a mutable sequence object (e.g., a list), the subscript must
yield a plain integer. If it is negative, the sequence's length is added to it. The
resulting value must be a nonnegative integer less than the sequence's length, and the
sequence is asked to assign the assigned object to its item with that index. If the
index is out of range, IndexError is raised (assignment to
a subscripted sequence cannot add new items to a list).
If the primary is a mapping object (e.g., a dictionary), the subscript must have a
type compatible with the mapping's key type, and the mapping is then asked to create a
key/datum pair which maps the subscript to the assigned object. This can either
replace an existing key/value pair with the same key value, or insert a new key/value
pair (if no key with the same value existed).
- If the target is a slicing: The primary expression in the reference is evaluated. It
should yield a mutable sequence object (e.g., a list). The assigned object should be a
sequence object of the same type. Next, the lower and upper bound expressions are
evaluated, insofar they are present; defaults are zero and the sequence's length. The
bounds should evaluate to (small) integers. If either bound is negative, the
sequence's length is added to it. The resulting bounds are clipped to lie between zero
and the sequence's length, inclusive. Finally, the sequence object is asked to replace
the slice with the items of the assigned sequence. The length of the slice may be
different from the length of the assigned sequence, thus changing the length of the
target sequence, if the object allows it.
(In the current implementation, the syntax for targets is taken to be the same as for
expressions, and invalid syntax is rejected during the code generation phase, causing less
detailed error messages.)
WARNING: Although the definition of assignment implies that overlaps between the
left-hand side and the right-hand side are `safe' (e.g., "a, b = b,
a" swaps two variables), overlaps within the collection of assigned-to
variables are not safe! For instance, the following program prints "[0,
2]":
x = [0, 1]
i = 0
i, x[i] = 1, 2
print x
|