Finding the instance reference of an object
Steve Holden
steve at holdenweb.com
Fri Oct 17 16:36:24 EDT 2008
Joe Strout wrote:
> On Oct 16, 2008, at 11:23 PM, Dennis Lee Bieber wrote:
[much blether]
>>> 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.
>
In [8]: def foo(x):
...: x += [42]
...:
In [9]: a = [1, 2, 3]
In [10]: foo(a)
In [11]: a
Out[11]: [1, 2, 3, 42]
In [12]: def ffoo(x):
....: x.append(43)
....:
In [13]: ffoo(a)
In [14]: a
Out[14]: [1, 2, 3, 42, 43]
In [15]: def fffoo(a):
....: a = a + [42]
....:
In [16]: fffoo(a)
In [17]: a
Out[17]: [1, 2, 3, 42, 43]
So, is it call by reference or not? Does that depend on the
implementation of specific operators?
You problem seems to be that you ar still stuck with the notion of a
name as a reference to a specific area of memory. Which it's not,
excepting only if you want to consider the area of memory that holds a
reference to some value.
In the case of lists,
a = a + [something]
rebinds a, while
a += [something]
doesn't. So where does that leave you?
> 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.
>
Be careful though:
In [18]: a = 42
In [19]: id(a)
Out[19]: 14237932
In [20]: a += 1
In [21]: id(a)
Out[21]: 14237920
In [22]: a = []
In [23]: id(a)
Out[23]: 2140206636
In [24]: a += [42]
In [25]: id(a)
Out[25]: 2140206636
In other words, the behavior of augmented operations depends on whether
the reference is to a mutable or an immutable value.
>> 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".
>
It might be simpler to say "Change this name to be a reference to that
value", or "Change this name to be a reference to the [result of
evaluating the] expression on the RHS".
Or indeed, "Change the content of that container element to be a
reference to the [result of evaluating the] expression on the RHS"
> 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.)
>
If you mean it's a reference assigment, of course it is. That's what he
was trying to say (I believe). But in C, for example,
int i;
i = 42;
actually stores the value 42 in the location associated with the name c.
Quite different from
int *i;
i = &42;
[Is that even valid C?] That's almost what Python does with
i = 42
>>> 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!
>
40 Mb! You were lucky! Etc., etc., [drools into beard.]
>>> 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.
>
Python's assignment semantics (as opposed to its "object handling, a
term for which I have no referent) are not the same as those of, say C.
I believe they are pretty much the same ass those of Icon, another
non-standard interpreted language.
There are close similarities between Python's names and C reference
variables, but the semantics are not exactly parallel.
People here don't describe Python as different just because they *want*
it to be different. Python acknowledges intellectual debts to many
languages, none of which is exactly like it.
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
More information about the Python-list
mailing list