On Oct 27, 2008, at 12:19 PM, [EMAIL PROTECTED] wrote:
I think this "uncontrived" example addresses the C/Python difference
fairly directly (both were tested):
That's correct, but of course, C is a decades-old language barely a
step above assembler. For a fair comparison, pick any modern OOP
language, including the C derivatives (C++, Objective-C, Java), and
compare a Python object to an object in that language, rather than to
a struct.
In Python, variables are just names/aliases for *references* to
objects, not names for the objects/values themselves. The variable
names themselves do not correspond directly to the objects' memory
locations.
Exactly! In C++, this would be like a pointer variable. In Java, RB,
or .NET, it's like an object reference.
While yes, technically, it is true that those reference
values must be stored somewhere in memory, *that* is the
implementation detail.
Agreed. (And this was my point in response to someone arguing that no
such location exists.)
But is is not the *locations* of these
references (i.e., the locations of the Python *variables*) that are
copied around, it is the references themselves (the locations of the
Python *objects*) that are copied.
Right. The variables contain object references; these object
references are copied (not referenced!) when you pass them into a
function. That's call by value. In the case of an assignment, the
reference is copied.
All that exists in Python is a name->object mapping.
And what does that name->object mapping consist of? At some level,
there has to be a memory location that stores the reference to the
object, right?
I think this is answered above, but just to drive it home, in Python
the memory locations of the variables themselves (an implementation
detail), which hold the references to the objects, are inaccessible .
Right. So too in Java, RB, .NET, etc. Pointers are nasty. But lack
of pointers does not change the calling semantics.
In C/C++, by contrast, variable names correspond directly to memory
locations and objects, and you can easily find the addresses of
variables.
Hmm, no, the C++ equivalent of an object reference would be:
SomeClass* foo;
In fact, many C++ programmers prefer to typedef a pointer to each
class, since it's the pointer (which is rough equivalent of a
reference in newer languages) that you almost always want, rather than
the class itself. So it would actually be:
SomeClassPtr foo;
Now, when you do:
foo2 = foo;
you are copying the object reference from foo to foo2, just as in
Python. When you pass it into a function:
void NiftyMethod(SomeClassPtr arg) {...}
...
NiftyMethod(foo);
You are copying the object reference right onto the call stack. This
is pass by value, plain and simple. And because it is pass by value,
you know that nothing NiftyMethod does can possibly change the value
of foo -- that is, can make it point at something else. (It may well
change the data that the object it points to contains, if SomeClass
objects are mutable, but it can't change foo itself.) This is, again,
just like Python and every other OOP language.
Call by reference would be this:
void NiftyMethod2(SomeClassPtr &arg) {...}
...
NiftyMethod2(foo);
Now, arg here is passed by reference (just like a ByRef parameter in
RB or .NET). That means that NiftyMethod2 could very well change the
value that is passed in. It could actually make foo point to
something else.
No Python method can do that, because Python arguments are ALWAYS
passed by value. There is no call by reference in Python. Period,
end of story, nothing to see here.
Cheers,
- Joe
--
http://mail.python.org/mailman/listinfo/python-list