python assignment

Tim Peters tim.one at comcast.net
Tue Jul 22 22:46:56 EDT 2003


[dan]
> without stirring the pot too much --
>
> could someone please point me to whatever documentation exists on the
> philosophy, semantics, and practical implications of how Python
> implements the assignment operator?

It's too simple to explain <0.5 wink>.  Fredrik does a good job here:

    http://effbot.org/zone/python-objects.htm

> So far I can't find much useful in the regular documentation.  I
> understand the basic concept that names are bound to objects
> which exist on the heap, but that still doesn't explain why a = b
> doesn't _always_ cause a to point to the same object as b.

That's because a = b does always cause a to point to the same object as b.
If you think you found a case where that's not true, you're missing
something.

> What determines when the object in question is copied?

The rule that the object in question is never copied.  There are no
exceptions to this.  Copying an object requires invoking some method of the
object, or applying some function to the object.  For example, d.copy()
returns a (shallow) copy of a dict d, and L[:] returns a (shallow) copy of a
list L.

> What determines when a future maniplulation of the variable
> will cause it to point to an object that is already referenced by
> another variable? (see code below for an example).

Phrase that more precisely, and it will answer itself <wink>.  Seriously, I
don't know what you're asking there.

> What I need is an exact and unambiguous algorithm for determining when
> an assignment will change the id of the variable

Variables don't have ids, but objects do.  Assignment never changes the id
of an object.

> (or should I say, when the evaluation of an expression will cause a
> new object to be created).

Expressions may or may not create new objects, but assignment isn't an
expression in Python (assignment is a statement), and an assignment never
creates a new object.

> Some of the issues involved can be discerned from the
> following session:
>
>>>> a = 1
>>>> b = a
>>>> a is b
> True

That one is necessarily True.  Immediately after

    a = b

and assuming b is bound to *something*,

    a is b

always returns True.  The history and type of the object bound to b makes no
difference.

>>>> a += 1
>>>> a -= 1
>>>> a is b
> True

That one isn't defined.  It could just as well return False.  Which it
returns is an implementation detail, and may vary across implementations of
Python (including across Python releases).

>>>> a = 1.0
>>>> b = a
>>>> a is b
> True

As above, that was necessarily True.

>>>> a += 1
>>>> a -= 1
>>>> a is b
> False

And again that one isn't defined.  It could just as well return True, and
depends on implementation details.

>>>> a == b
> True

That one is fuzzy, because floating-point arithmetic is involved, and that's
subject to roundoff errors.

Note that

    x += y

isn't *just* an assignment statement, it's syntactic sugar for the
assignment

    x = x.__iadd__(y)

Whether the __iadd__() method of an object returns a pre-existing object, or
returns a new object, isn't defined in general.  It's up to each type's
implementation of __iadd__ to decide what it wants to do.  As an internal
optimization, the __iadd__ method of some immutable types chose to return
pre-existing objects *when that's convenient* for them.  It would be very
unusual (because bad design) for the __iadd__ method of a mutable type to
return a pre-existing object, though.






More information about the Python-list mailing list