Modifying Class Object

J

John Posner

Alf said (2/13/2010 8:34 PM):
Names in Python refer to objects.

Those references can be copied via assignment.

That's (almost) all.

And it provides a very short and neat way to describe pass by sharing.

Alf also said (2/13/2010 8:43 PM):
* Steve Howell:

I think that regarding the technical it is whether a Python name
refers to an object or not. I maintain that it does, and that the
reference can be copied, and that the semantics of the language
requires this and is defined in terms of this. Steve Holden,
D'Aprano and many others maintain that there are no references, or
that if there are then they're only an implementation aspect, i.e.
that conceiveable one could have an implementation without them.

Steve D'Aprano said (2/14/2010 12:13 AM):
That's not to say that the general concept of references (as in "to
refer to") isn't valuable when discussing Python. If you want to say
that (e.g.) following

x = 1

the name "x" refers to (or even points to!) the object 1, my
objections will be mild or non-existent. In that sense, it's probably
impossible to program without some sort of "references": the computer
manipulates variables or objects directly, while we manipulate
characters in source code. The only way to write a program is to use
some abstract thing (a name, an offset, whatever) that refers, in
some fashion, to a collection of bits in the computer's memory. But
to go from that to the idea that (say) x is a pointer does so much
violence to the concept of pointer and has so much room for confusion
that it is actively harmful.

I think most of the technical argument in this thread comes down to the
various forms of the word *refer*. After execution of this Python statement:

x = 5

.... we can use this English-language statement:

the name *x* refers to the value *5*

(If anyone has more than Steve's "mild" objection, please speak up!)

The English-language statement uses the VERB "refers". It is not the
same as using the NOUN "reference":

*x* is a reference to the value *5*

Why not? Because using the NOUN form suggests that you're talking about
a particular kind of object in the world Python, as in these statements:

*x* is a string
*x* is a function
*x* is a class

But Python does not define *reference* objects -- by which I mean that
executing *import types; dir(types)* produces a long list of object-type
names, and there's nothing like a "reference" on that list.

(I suspect there's a better way to make this "there are no reference
objects" argument. Can anyone help?)

Amending the statement to:

the name *x* is a reference to the value *5*

.... doesn't really help matters. Is *x* a NAME or is it a REFERENCE?

Looking again at Alf's assertion:
[the core technical question is] whether a Python name
refers to an object or not. I maintain that it does, and that the
reference can be copied,

.... and Alf's example (message dated 2/10/2010 5:02 PM):
For example,

x = s[0]

accesses the object that s points (refers) to.

I believe Alf would characterize this assignment statement as a
situation in which "a reference is copied" [using the NOUN form of
"refer"]. But no object is copied during execution of this statement.
Moreover, saying "a reference is copied" might mislead a Python newbie
into thinking that some kind of "reference object" exists that can be
copied by Python statements. So it's better to describe the situation
using the VERB form of "refer":

assigns the name *x* to the object that *s[0]* refers to


-John
 
S

Steven D'Aprano

John Posner said:
[...]
assigns the name *x* to the object that *s[0]* refers to

s[0] does not refer to an object, it *is* an object (once evaluated of
course, otherwise it's just a Python expression).

Precisely. Treated as an expression, that is, as a string being evaluated
by the compiler, we would say that it *refers to* an object (unless
evaluation fails, in which case it refers to nothing at all). But treated
as whatever you get after the compiler is done with it, that is, post-
evaluation, we would say that it *is* an object.

This subtle distinction is essentially the difference between a label and
the thing that is labeled.
 
A

Alf P. Steinbach

* Steven D'Aprano:
John Posner said:
x = s[0] [...]
assigns the name *x* to the object that *s[0]* refers to
s[0] does not refer to an object, it *is* an object (once evaluated of
course, otherwise it's just a Python expression).

Precisely. Treated as an expression, that is, as a string being evaluated
by the compiler, we would say that it *refers to* an object (unless
evaluation fails, in which case it refers to nothing at all). But treated
as whatever you get after the compiler is done with it, that is, post-
evaluation, we would say that it *is* an object.

This subtle distinction is essentially the difference between a label and
the thing that is labeled.

The main differences between a pure functional language where that view can hold
and be reasonable, and a language like Python, are that

* Python assignments change which object a name refers to, /at runtime/.

- Name binding is run time action, not a compile time action.
Without run time binding names couldn't be reassigned. s = 1; s = 2

* Some Python objects are modifiable (a.k.a. mutable).

- This is particularly important when two or more names refer to the
same object and that object is modified.

That is, a simple-minded transfer of concepts from pure functional programming
to Python breaks down in these cases[1].

I hope this explanation of exactly where the functional programming enthusiasts
here go wrong can be of help to readers of the thread, although I've given up
hope on those holding the functional programming view (since I'm only human, and
even the Gods contend in vain against that sort of thing).


Cheers & hth.,

- Alf

Notes:
[1] Steven D'Aprano's focus on compilation rather than execution mainly ignores
the first point, that a name in given a statement in a loop, say, can refer to
different objects in different loop iterations. Happily the Python language
specification explains binding as a run-time action. Binding is not a compile
time action in Python, it is a run-time action, and can bind a given name in a
given statement within the same routine execution, to different objects, and the
language specification of course uses the phrase "refers to" to explain the
situation after a run time binding.
 
J

John Posner

John Posner said:
x = s[0] [...]
assigns the name *x* to the object that *s[0]* refers to

s[0] does not refer to an object, it *is* an object (once evaluated of
course, otherwise it's just a Python expression).

Precisely. Treated as an expression, that is, as a string being evaluated
by the compiler, we would say that it *refers to* an object (unless
evaluation fails, in which case it refers to nothing at all). But treated
as whatever you get after the compiler is done with it, that is, post-
evaluation, we would say that it *is* an object.

This subtle distinction is essentially the difference between a label and
the thing that is labeled.

Is this your only quibble with my writeup? If, so, I'm gratified. And
your objections make perfect sense. Still, I'll attempt to justify my
phrasing. I was originally going to write:

assigns the name *x* to the object that THE NAME *s[0]* refers to

.... but I didn't want to start a distracting argument on the use of the
phrase *the name* to describe the 4-char string *s[0]*. So now I'll try
to (briefly) make my case.

Yes, it might be more correct to say that *s[0]* is an expression
(equivalent to the more obvious expression *s.__getitem__(0)*). But in
common usage, the 4-char string *s[0]* _behaves_ like a name. If you
accept this viewpoint, the story on Python assignment statements becomes
quite simple ...

Syntactic sugar aside, there are only two kinds of assignment statements:

1. NAME = EXPRESSION

The EXPRESSION creates a new object, and the NAME is assigned to that
object. Examples:

x = x + 1
obj = MyClass(1, 2, "red")
mywordlist = mysentence.split()

2. NAME2 = NAME1

No new object is created. NAME2 becomes another name (an "alias") for
the existing object that currently has NAME1 assigned to it. Examples:

y = x
s[0] = s[42]
mydict["spamwich"] == this_sandwich
obj.color = MYCOLORS.LTGREEN

This viewpoint might fail in advanced areas of Python programming:
properties/descriptors, double-underscore methods, etc. But in my own
day-to-day usage (admittedly, I'm a hobbyist Python programmer, not a
professional), it's never failed me to think this way:

* A dict is a collection of user-devised names, each of which
is assigned to an object.
* A list/tuple is an interpreter-maintained collection of integer
names (0, 1, 2, ...), each of which is assigned to an object.
* A class instance is very much like a dict.

Tx,
John
 
A

Albert van der Horst

Alf said:
* Steve Holden:
Alf P. Steinbach wrote: [snip]

Since in the quoting above no reference to definition of "pointer"
remains: "pointer" refers to a copyable reference value as seen from the
Python level, in the same way as "pointer" is used by e.g. the Java
language spec.
[snip]

If so, then that's correct: a Python (or Java, or whatever language)
pointer is not necessarily directly a memory address, and furthermore id
is not guaranteed to reproduce the bits of a pointer value -- which
might not even make sense.

All that id does is to produce a value that uniquely identifies the
object pointed to, i.e. it corresponds to the pointer value, and
although in CPython that's simply the bits of a C pointer typed as
integer, in IronPython it's not.

You go too far here. What you are referring to in your bizarrely
constructed definition above

No, it's not bizarre, it's the standard general language independent
definition.
*The* standard general language independent definition? As defined
where? The id() value doesn't "correspond to the pointer value", it
corresponds to the object. Why you see the need for this indirection
remains a mystery.

No it doesn't. If an object is garbage collected, the id() might be
recycled. At that time the id() corresponds to quite a different
object. OTOH if you kill an object in Python it is gone forever.
Of course there is a standard computer science idea of what a pointer is.
If you admit the pointer terminology, you can understand
that a pointer value is all what id() can tell us.

You seem to subsconsciously substitute "assembler language address"
for it. When someone says: "pointers are bad" what really meant is
"manipulating assembler language addresses in a high level language
is bad". (Everybody agrees, but sometimes you must use e.g. c
as sort of assembler.)
That is not the kind of pointers we're talking about here.

(I once studied algol 68, and never got confused about these
subjects anymore, recommended.)
regards
Steve

Groetjes Albert
 
N

NevilleDNZ

Hi Groetjes Albert,

I spotted your comment - re: pointers
http://groups.google.com/group/comp.lang.python/msg/5c1e25919b6a74bf

On Feb 22, 11:44 pm, Albert van der Horst <[email protected]>
wrote:
(I once studied algol 68, and never got confused about these
subjects anymore, recommended.)

Having used Algol68, then switching to C to discover "*" for manual
dereferencing I immediately wanted to be back using A68 again, but
alas... Then when I switched to C++ I immediately understood the
"Zen" of C++'s "&"... but still wanted to switch back to A68. Was
there ever a version with "Objects"... I saw a version with "Areas"
but have no idea what an "Area" is.

@Albert: Given the domain name "xs4all" in your email address I am
sure YOU have spotted: http://www.xs4all.nl/~jmvdveer/algol.html by
Marcel

Also: I invite you to join one of the below groups (my .sig below) and
deposit some of your Algol68 impressions....

There is also a chrestomathy site http://rosettacode.org/wiki/ALGOL_68
where you can pick out an code sample unimplemented in Algol68 and
torture test your Algol68 memories. (Be warned: Most of the easy
samples are done)

Keep in touch
NevilleDNZ
--
For Algol68-user mailinglist with archives & subscription:
* https://lists.sourceforge.net/lists/listinfo/algol68-user
To download Linux's Algol68 Compiler, Interpreter & Runtime:
* http://sourceforge.net/projects/algol68
Join the linkedin.com's Algol68 group, follow:
* http://www.linkedin.com/groups?gid=2333923
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top