Finding the instance reference of an object

Joe Strout joe at strout.net
Fri Oct 17 17:56:17 CEST 2008


On Oct 16, 2008, at 11:23 PM, Dennis Lee Bieber wrote:

> On Thu, 16 Oct 2008 21:19:28 -0600, Joe Strout <joe at strout.net>
> declaimed the following in comp.lang.python:
>
>> Now that IS mysterious.  Doesn't calling a function add a frame to a
>> stack?  And doesn't that necessitate copying in values for the
>> variables in that stack frame (such as 'x' above)?  Of course we're
>
> 	No -- it copies the /reference/ to the object containing the value.

The reference to the object IS the value of an object reference  
variable.  So good, parameters are passed ByVal in Python as they  
appear to be, and as is the default in every other modern language.

> Just as assignment transfers the reference to the RHS object to the  
> name
> shown on the LHS.

Assignment copies the RHS value to the LHS variable.  In the case of  
an object reference, the value copied is, er, an object reference.

>> The semantics here appear to be exactly the same as Java or REALbasic
>> or any other modern language: variables are variables, and parameters
>> are local variables with called by value, and it just so happens that
>> some values may be references to data on the heap.
>>
> 	ALL "values" are references to data in Python -- but some of those
> values are immutable objects so any operation performed on them  
> creates
> new objects, and the assignment is of a new reference.

OK, that part is a little different from most languages -- not in the  
way objects are treated, but in the fact that even simple values like  
integers are wrapped in objects.  But since those are immutable  
objects, this is mostly an internal implementation detail.

For object references (including the mutable ones that may treat  
people up), Python's behavior is no different from any other language.

>>> (Answer: neither. They are call by name.)
>>
>> I have no idea what that means.  They're call by value as far as I  
>> can
>> tell.  (Even if the value may happen to be a reference.)
>
> 	Technically, as I recall the definition of "call by name", they
> aren't that either. ...
> Call by name, then, acted as a macro expansion wherever the argument
> was referenced in the called function.

Thanks for that explanation.  Clearly that's not what's going on in  
Python.

>> Side question, for my own education: *does* Python have a "ByRef"
>> parameter mode?
>>
> 	As far as I'm concerned -- everything is "by ref" in Python...

No, a "by ref" parameter would mean that this:

def foo(ByRef x):
  x = x + [42]

a = [1,2,3]
foo(a)

...would result in a = [1,2,3,42].  You would only be able to pass a  
simple variable (not an expression or literal) to foo, and the 'x'  
inside foo would not be a local variable, but an alias of whatever  
variable was passed in.  Thus any assignments to it would affect the  
original variable that was passed in.

But if Python has any such feature, I'm not aware of it.  Certainly  
the default behavior is to pass everything (even object references) by  
value.  Assignments made to them don't affect anything else.

> 	Mutation of an object is never a bare LHS... It is either a method
> call of the name
>
> 	alist.append()
>
> or a drill-down going inside the object
>
> 	alist[2] = something
> 	anobject.attribute = something
> 	adict["key"] = something

Or, use of one of the compound operators like +=.  That's the only  
real "gotcha" in Python to somebody coming from another language; you  
might naively expect that x += y is the same as x = x+y, but in Python  
this is not generally the case; instead += is a mutation operator,  
like the examples you show above.

> 	But every language I've used (many: FORTRAN, C, C++, BASIC, VB,
> Assembly, COBOL, Ada...) treats "variable" as "name of fixed  
> location in
> memory" and assignment to the variable means "replace the contents of
> the location of memory associated with this name with the contents of
> memory to which that name (may be anonymous in the case of an
> expression) is associated by copying the contents from there to here"

That's what Python does too.  It just so happens that the fixed  
location in memory contains an object reference.  No difference here  
between Python's object references VB.NET's object references, C++  
pointers, Java object references, etc. etc.

> 	Python, OTOH, ALWAYS handles assignment as "change the memory
> association of this name to be the same as that name".

What does that mean, exactly?  It means: "replace the contents (i.e.  
object reference) of the memory location associated with this name  
with the contents (i.e. object reference)  of the memory to which that  
name is associated by copying the contents from there to here."

It's the exact same thing.  (And exactly the same as in any other  
language.)

>> No, but if we define them in the standard way, and point out that
>> Python variables behave exactly like variables in other languages,
>> then that IS helpful.
>>
> 	But they don't...

They really, really do.

>> But it's not at all surprising with lists and dicts and objects --
>> every modern language passes around references to those, rather than
>> the data themselves, because the data could be huge and is often
>> changing size all the time.  Storing the values in a variable would
>> just be silly.
>>
> 	In most all of those languages, one has to explicitly differentiate
> the the difference between a copy and a reference.

Only if you're thinking of languages from 20 years ago or more.  Even  
in C++, while there is a different bit of kludgy syntax for object  
"references" (because they're mere pointers), it's the standard to use  
such pointers everywhere that objects are handled.  Java cleaned up  
that kludginess by replacing the pointers with proper references, as  
did VB.NET, REALbasic, probably Ruby, and of course Python.

> And even that is not
> assured... As I recall, nothing in the Ada language reference forbids
> implementing an "in out" procedure parameter from being implemented  
> via
> copy-in/copy-out semantics rather than via reference.

Hah, well probably so.  Ada even predates me, and I'm not all that  
young anymore!

>> Hmm... I bet you're over 30.  :)  So am I, for that matter, so I can
>> remember when people had to learn "pointers" and found it difficult.
>
> 	Bah... The roots of I/O in Pascal required pointer dereferencing.

Hey, I remember Pascal... that was the language used on the Apple  
IIGS, back when I was in junior high.  I also remember spending $800  
for a 40MB hard drive for it.  Ah, those were the days!

>> So, if the semantics are all the same, I think it's helpful to use  
>> the
>> standard terminology.
>>
> 	But, it seems, you are the only one arguing that "the semantics are
> all the same"... Doesn't that suggest that they aren't the same?

No, it suggests to me that there's a lot of confusion in the Python  
community.  :)  It appears as though people either (a) really want to  
think that Python's object handling is special and unique for  
emotional reasons, or (b) are comparing it to really ancient languages  
that didn't have any notion of objects and object references.  This  
has led to making up new terminology and spreading confusion.  I'm  
coming back to Python from almost a decade of working with other  
modern languages (including implementing the compiler for one of  
them), and I don't see any difference at all between Python's object  
handling and those.

Best,
- Joe





More information about the Python-list mailing list