Finding the instance reference of an object

Joe Strout joe at strout.net
Mon Oct 27 15:11:04 EDT 2008


On Oct 27, 2008, at 12:19 PM, gooberts at gmail.com 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



More information about the Python-list mailing list