The meaning of "=" (Was: tough-to-explain Python)

kj no.email at please.post
Wed Jul 8 16:04:35 CEST 2009


In <h30e3t$g56$2 at reader1.panix.com> kj <no.email at please.post> writes:

>I had not realized how *profoundly* different the meaning of the
>"=" in Python's

>  spam = ham

>is from the "=" in its

>  spam[3] = ham[3]


To clarify, this comes from my reading of Fredrik Lundh's pages
"Python Objects" (http://effbot.org/zone/python-objects.htm) and
"Call By Object" (http://effbot.org/zone/call-by-object.htm).
(Thanks to Chris Rebert for the pointer!)

In the first one of these pages, Lundh writes:

[START OF LENGTHY QUOTE]

  Assignment statements modify namespaces, not objects.

  In other words,

  name = 10

  means that you're adding the name 'name' to your local namespace,
  and making it refer to an integer object containing the value
  10.

  If the name is already present, the assignment replaces the
  original name:

  name = 10
  name = 20

  means that you're first adding the name 'name' to the local
  namespace, and making it refer to an integer object containing
  the value 10. You're then replacing the name, making it point to
  an integer object containing the value 20. The original '10'
  object isn't affected by this operation, and it doesn't care.

  In contrast, if you do:

  name = []
  name.append(1)

  you're first adding the name 'name' to the local namespace, making
  it refer to an empty list object. This modifies the namespace.
  You're then calling a method on that object, telling it to append
  an integer object to itself. This modifies the content of the
  list object, but it doesn't touch the namespace, and it doesn't
  touch the integer object.

  Things like name.attr and name[index] are just syntactic sugar
  for method calls. The first corresponds to __setattr__/__getattr__,
  the second to __setitem__/__getitem__ (depending on which side
  of the assignment they appear).

[END OF LENGTHY QUOTE]

Therefore, extending just a bit beyond Lundh's explanation, if we
did:

name = []
name.append(1)
name[0] = 3

...the second assignment would amount to a method call on the object
called 'name', an operation of a very different nature (according
to Lundh) from the first assignment, which is a modification of a
namespace.

In the second one of these pages, Lundh makes a very similar point
(third post from the bottom).

But note that Lundh appears to be contradicting himself somewhat
when he writes "Assignment statements modify namespaces, not
objects."  If by "assignment statements" he means ones consisting
of a left operand, a "=", and a right operand, then according to
the rest of what he writes on this subject, this assertion applies
only to *some* assignment statements, namely those of the form

  <identifier> = <expression>

and not to those like, for example,

  <identifier>[<expression>] = <expression>

or

  <identifier>.<identifier> = <expression>

The former are syntatic sugar for certain namespace modifications
that leave objects unchanged.  The latter are syntactic sugar for
certain object-modifying method calls that leave namespaces unchanged.

At least this is how I interpret what Lundh writes.

kj




More information about the Python-list mailing list