Finding the instance reference of an object

Joe Strout joe at strout.net
Tue Nov 4 18:19:08 EST 2008


On Nov 4, 2008, at 3:54 PM, Steven D'Aprano wrote:

> At the level of Python code, Python operates on *objects*. When you  
> call
> a function with an argument, the argument (an object) is NOT copied,  
> it
> is passed to the function. If you mutate the argument inside the
> function, you are changing the object and the caller will see the
> mutation: this is just like call-by-reference, and unlike call-by- 
> value.

And here is the key bit that you are missing.

When you pass a reference to an object to a function, and then mutate  
the object, then OF COURSE the caller (as well as any other holders of  
a reference to that object) will see the mutation.  This is true in  
ANY language.  Pick your language, and I will demonstrate it.  Here  
are a few to get us started (assume a class "Person" with an attribute  
"zipcode"):

C++:
void foo(PersonPtr who) {
	who->zipcode = 12345;
}

Java:
void foo(Person who) {
	who.zipcode = 12345;
}

REALbasic/VB.Net:
Sub foo(ByVal who as Person)
	who.zipcode = 12345
End Sub

Python:
def foo(who):
	who.zipcode = 12345


So please clarify your position by identifying which statement applies:

1. You don't believe that these languages are actually passing by value.
2. You don't believe these examples are mutating an object.
3. You don't believe these mutations can be seen by the caller after  
the call.
4. You now see how a mutating an object within a function tells you  
NOTHING about how the reference to that object was passed.
5. You see that the first three languages above are passing a  
reference by value and using that to mutate and object, yet for  
reasons still mysterious, the Python example (which has exactly the  
same behavior) must be doing something different.

I hate being confrontational, but you're the one accusing me of  
ignoring evidence against my "pet theory" (by which you mean the  
standard definitions of c-b-v and c-b-r).  Let's see what you do with  
this evidence that directly contradicts yours.

Sigh.

> But if you assign a different object to the argument name, the caller
> does NOT see the change, which is just like call-by-value.

This at least you have correct.

> So depending
> on what type of object the argument is, and depending on what you do
> inside the function, you get something that looks rather like call-by-
> value or call-by-reference semantics.

But no, you don't, as I just demonstrated above (and explained a week  
ago at <http://www.strout.net/info/coding/valref/>).  You always have  
call-by-value semantics.  The semantics are exactly the same as in any  
other language with anything resembling an object reference, including  
those with both "ByVal" and "ByRef" modes (except that there is no  
equivalent to the "ByRef" mode in Python).

> But what the Python VM does is the
> same no matter what you do: Python's calling model is different from
> either byval or byref.

No, it's exactly byval.  No.  Different.  In.  Any.  Way.

Let's tackle it this way: one of the following must be true for your  
belief system to prop itself up at all:

1. Python's behavior is different from Java, REALbasic, VB.NET, and C++.
...or...
2. None of those languages mentioned use call-by-value.

In fact both of these statements are false, but we can cut our time  
and effort in half if you will just select the one that you believe to  
be true, so we can focus on that.  Which is it?

Thanks,
- Joe




More information about the Python-list mailing list