the deceptive continuous assignments

Terry Reedy tjreedy at udel.edu
Tue Dec 6 07:20:45 EST 2011


On 12/6/2011 6:06 AM, Yingjie Lan wrote:
> Hi, I just figured out this with Python3.2 IDLE:
>
>>>> class k: pass
>>>> x=k()
>>>> x.thing = 1
>>>> x.thing
> 1
>>>> x = x.thing = 1
> Traceback (most recent call last):
>    File "<pyshell#7>", line 1, in<module>
>      x = x.thing = 1
> AttributeError: 'int' object has no attribute 'thing'
>>>> x
> 1
>>>>
>
> ================
> when I do x=x.thing=1, I thought it would
> be like in C, 1 is first assigned to x.thing,
> then it is further assigned to x.

In C, assignments are expressions, not statements.
a = b = c is parsed as a = (b = c). a get the result of (b = c), which 
happens to be c.

In Python, the syntax really should be a =, b = c in that the 
assignments are more in parallel.

> But what seems to be going on here is
> that 1 is first assigned to x, then
> to x.thing (which causes an error).
>
> Any reason why would Python deviate
> from C in this regard?

Python is consistently left to right in expression evaluation. For 
assignment, it first does left to right on the source side, and then on 
the target side.

"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."

You have two target lists. x,x.thing = 1,2 would assign 1 to x and then 
get an error trying to assign a different object to x.thing. In your 
case, you get an error trying to assign the same object rather than a 
different object, but the principle is the same.

"WARNING: Although the definition of assignment implies that overlaps 
between the left-hand side and the right-hand side are ‘safe’ (for 
example a, b = b, a swaps two variables), overlaps within the collection 
of assigned-to variables are not safe!"

You found an unsafe overlap.
x.thing = x = 1
would work, though it seems strange (and unlikely in practice) to rebind 
x to an int after it is bound to a class k instance.

-- 
Terry Jan Reedy





More information about the Python-list mailing list