how to pass by reference??

Aahz Maruch aahz at panix.com
Fri Mar 8 11:24:04 EST 2002


[after letting this sit for a couple of weeks, I decided I wanted to
make a couple more additions; I'm leaving this mostly unsnipped for
clarity.]

In article <Mfw88.94809$KM2.3437354 at atlpnn01.usenetserver.com>,
Steve Holden <sholden at holdenweb.com> wrote:
>"Aahz Maruch" <aahz at panix.com> wrote in message
>news:a3sklt$7vr$1 at panix2.panix.com...
>> 
>> Um, that's not IMO/IME a particularly useful way to look at it.  I don't
>> remember who first proposed it, but I find talking about "names" and
>> "bindings" to be much clearer.  When talking about parameter passing, one
>> would say that the function parameters create new names that get bound to
>> the passed in objects.  Any time one uses assignment on the function
>> parameter names (or any other name in Python, for that matter), the name
>> gets rebound to a different object.
>>
>Maybe we should beat this one to death with a rock ;-)  I should point out
>this is not for Aahz' benefit, since he knows it already.
>
>Any time one uses assignment, one causes a name to be bound to an object.
>Argument passing is actually binding a name (the argument name, present in
>the function's local namesspace) to an existing object -- whatever was
>passed as an argument, whether it was written as a complex expression (which
>could create an object "on the fly") or simply as an existing name (which
>would be a simple reference to an existing object).
>
>Assignment to the argument name inside the function, as Aahz points out,
>simply rebinds the argument name to a new value. Which means that such an
>assignment will not change the object passed as an argument.
>
>Assignment to *a component of the argument*, however, is a completely
>different case (as I think someone else has already pointed out). So, if you
>pass in to a function an argument arg, the assignment
>
>    arg = something_new
>
>will leave the argument object completely unaltered. However, the assignment
>
>    arg[0] = something_new
>
>will modify a list argument, and this modification will be visible outside
>the function as well as inside it. You have mutated the object passed as an
>argument, and so all names bound to that object will access the mutated
>value. Similarly with arg.attr = something.new, arg.append(something), and
>so on.

In the case of arg[0], this is Python's special syntactic sugar for
turning an assignment into a method call:

    arg.__setitem__(something_new)

As pointed out earlier, this still involves a binding (because methods
are functions), but it's hidden through the method call.  In fact, there
are actually two bindings, one for the method call itself and one inside
the method when it mutates the object.

In the case of arg.attr, I think it should be made clear that in Python
the "." is a signifier for namespace access.  That is, "arg.attr" should
probably be written as namespace.attr for the purpose of this
discussion.  That makes it clearer that you can do things like this:

    import foo
    foo.bar = something_new

    def f():
        pass
    f.a = something_new

>> If the object is mutable and mutated, all names that are bound to that
>> object see the changes.  Mutation, by definition, *never* involves a
>> rebinding of the object being mutated (that is, mutation never takes
>> place in an assignment -- though of course the assignment expression
>> might involve mutation as a side-effect).
>>
>You have to be careful to distinguish here between simple assignments (x =
>expr) and augmented assignments (x += expr), since the latter are explicitly
>allowed to mutate the object referenced by the name, but need not do so if
>the implementation of the object concerned chooses not to. The former, I
>agree, are simple rebindings.

Again, augmented assignment translates into a method call; whether the
method returns the original object or a new one depends primarily on
whether the object implementing the method is mutable or immutable.

>> (Yes, you're talking about binding, but you don't go whole hog, which
>> confuses the issue.)
>>
>I didn't get where I am today by not going the whole hog <wink>.
>
>luckily-tim's-at-developers'-day-ly y'rs  - steve

Not anymore!

(I'm doing this followup primarily for myself, as part of the tutorial
I'm hoping to do for OSCON this year.)
-- 
                      --- Aahz  <*>  (Copyright 2002 by aahz at pobox.com)

Hugs and backrubs -- I break Rule 6                 http://www.rahul.net/aahz/
Androgynous poly kinky vanilla queer het Pythonista

"Argue for your limitations, and sure enough they're yours."  --Richard Bach



More information about the Python-list mailing list