Something in the function tutorial confused me.

Alex Martelli aleax at mac.com
Sun Aug 12 02:23:02 CEST 2007


Neil Cerutti <horpner at yahoo.com> wrote:
   ...
> OK, I've thought about this some more and I think the source of
> my confusion was I thought assignment in Python meant binding a
> name to something, not mutating an object. But in the case of
> augmented assignment, assignment no longer means that?

"Plain" assignment *to a plain name* does mean "binding a name" (the
LHS) to "something" (the RHS).

Other assignments (ones that are not "plain" assignments to names) may
have different meanings.  For example:

>>> class act(object):
...   def __init__(self, c): self._c = c
...   def getC(self): return self._c
...   def setC(self, *ignore): self._c += 1
...   c = property(getC, setC)
...   
>>> x = act(0)
>>> x.c
0
>>> x.c = 23
>>> x.c
1
>>> 

Here's an example where a plain assignment (to an attribute of x, not to
a plain name) obviously DOESN'T mean "binding a name to something": the
"something" (the RHS) is completely ignored, so the plain assignment is
mutating an object (x) and not binding any name to anything.

Plain assignments to items and slices can also often be best seen as
"mutating an object" (the one being indexed or sliced on the LHS) rather
than "binding a name".  For example:

>>> l=list('ciao')
>>> l[1:3]='app'
>>> l
['c', 'a', 'p', 'p', 'o']

If I was teaching Python and came upon this example, I would definitely
not try to weaselword the explanation of what's going on in terms of
"binding a name" (or several ``names'', including ``rebinding" a new
``name'' l[4] to the 'o' that was previously ``bound'' to l[3], etc:-):
it's just orders of magnitudes simpler to explain this as "mutating an
object", namely the list l.

I take almost 3 pages in "Python in a Nutshell" (47 to 49 in the second
edition) to summarily explain every kind assignment -- and that's in a
work in which I've tried (successfully, I believe from reviews) to be
very, *VERY* concise;-).

Summarizing that summary;-), a plain assignment to an identifier binds
that name; a plain assignment to an attribute reference x.y asks object
x (x can be any expression) to bind its attribute named 'y'; a plain
assignment to an indexing x[y] (x and y are arbitrary expressions) asks
object x to bind its item indicated by the value of y); a plain
assignment to a slicing is equivalent to the plain assignment to the
indexing with an index of slice(start, stop, stride) [[slice is a Python
builtin type]].

Plain assignment to an identifier "just happens"; all other cases of
plain assignment are requests to an object to bind one or more of its
attributes or items (i.e., requests for specific mutations of an object)
-- as for, say any method call (which might also be a request for some
kind of mutation), the object will do whatever it pleases with the
request (including, perhaps, "refusing" it, by raising an exception).

Then we get into unpacking assignments and augmented assignments, but I
don't really want to write two more pages worth of summary...;-).


Alex



More information about the Python-list mailing list