469,330 Members | 1,266 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,330 developers. It's quick & easy.

Is 'everything' a refrence or isn't it?

I was under the assumption that everything in python was a refrence...

so if I code this:
lst = [1,2,3]
for i in lst:
if i==2:
i = 4
print lst

I though the contents of lst would be modified.. (After reading that
'everything' is a refrence.)
so it seems that in order to do this I need to code it like:

lst = [1,2,3]
for i in range(len(lst)):
if lst[i] == 2:
lst[i]=4
print lst

Have I misunderstood something?

Jan 4 '06
161 6678

Steven D'Aprano wrote:
On Fri, 06 Jan 2006 02:19:29 -0800, bonono wrote:

Steven D'Aprano wrote:
I'll tell you what I say: Python passes objects to functions or
assignments.

Which in C sense, is a reference(or pointer) to some opaque "table"
maintain by the system, identified by id().


And that C sense is precisely why people try using C idioms in Python and
then are surprised that they don't behave as they would in C.

So how about we all agree to stop implying that Python behaves like C, and
try to teach people that Python behaves like Python?

No one implies Python behaves like C but just trying to explain as
close as possible to people speaking that language.

"passed by object" can just as easilly be interpreted as "the function
received a seperate copy", with the caller's copy untouched.

Jan 6 '06 #51

Steven D'Aprano wrote:
But in programming, things do work that way. If my class Book contains a
reference to Smith's classic work, I can modify it. (Unless the language
deliberately restricts my ability to modify certain objects, as Python
does with immutable objects.)

That's what programmers expect when you talk about references, especially
if they come from a C (or Pascal) background. In Python, sometimes that's
true, and sometimes it is not, and the only way to tell is by looking at
the object itself, not by thinking about Python's high-level behaviour.


I believe one can restrict modification to pointer/reference parameter
passing to C function, so C programmer shouldn't have problem knowing
that reference doesn't not necessary mean you can modify it.

Jan 6 '06 #52
Ernst Noch <en***@gmx.net> writes:
Maybe next time showing something like the following trivial snippet
might help demonstrate that the core of the matter doesn't is not the
way python treats parameters?
Did you insert an extra "doesn't" in that? If so, then I agree about
what isn't the core of the matter.

On the other hand, the snippet doesn't help without an
explanation. Especially with misleading comments.
def func(param, what):

if what:
param['foo'] = 'changed'
else:
temp = param['foo'] # temp is _not_ a reference!


Except temp *is* a reference. What it's not is a reference to
param['foo']. Instead, it's a reference to the same object that
param['foo'] is a reference to.
temp = 'changed'


<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jan 6 '06 #53
Mike Meyer wrote:
Ernst Noch <en***@gmx.net> writes:
Maybe next time showing something like the following trivial snippet
might help demonstrate that the core of the matter doesn't is not the
way python treats parameters?

Did you insert an extra "doesn't" in that? If so, then I agree about
what isn't the core of the matter.


Uhm, yes. Seems the whole message was written too hastily.

On the other hand, the snippet doesn't help without an
explanation. Especially with misleading comments.
Absolutely, it was mainly meant as an example to demonstrate in practice
that the way python passes parameters has nothing to do with what happens.

>def func(param, what):


if what:
param['foo'] = 'changed'
else:
temp = param['foo'] # temp is _not_ a reference!

Except temp *is* a reference. What it's not is a reference to
param['foo']. Instead, it's a reference to the same object that
param['foo'] is a reference to.


Oh dear, yes. I inserted that comment as an afterthought.


Jan 6 '06 #54
In article <pa****************************@REMOVETHIScyber.co m.au>,
Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
I'll tell you what I say: Python passes objects to functions or
assignments.

Does this mean that the object is copied? No, I didn't say it copies
objects. I left the nature of the passing mechanism unspoken, which is how
it should be because it is an implementation detail.
Thus conveniently deferring the necessary explanation of how
it actually works, which will not be too hard but resists
simplistic "use this word" solutions.
The emphasis is on the *object*, not the passing mechanism. In C,
everything is mutable, and whether you can change an item depends on
whether you are working with a reference to that item or a copy of the
item. That's a language issue, not a data issue -- in some languages,
you can even choose whether to pass a reference to a function or a copy
of the value.

In Python, whether or not you can change an object depends on the object,
not the language itself: it is a data issue.


Oh, baloney. Same in C -

$ cc -c /tmp/t.c
/tmp/t.c: In function 'churk':
/tmp/t.c:4: error: assignment of read-only location

As long as you pass by pointer, it is much the same -

void
churk(const char *data)
{
data[0] = 'C'; /* error - modify const object */
data = "C"; /* no problem here - rebind pointer parameter */
}

Maybe the cure for hardened C programmers who aren't
getting it is to emphasize the pointer angle - and note
that there isn't any way to write "*i = 4". "Everything
is a pointer", let's say -- or maybe, "Everything is a
reference" would be smarter.

C programmers are used to seeing their data called
objects, too. (Not to mention the unlucky many of
us who learned OOP via C++.)

Donn Cave, do**@u.washington.edu
Jan 6 '06 #55
On Fri, 06 Jan 2006 20:49:06 +1100
"Steven D'Aprano" <st***@REMOVETHIScyber.com.au> wrote:
On Thu, 05 Jan 2006 22:18:39 -0600, Terry Hancock wrote:
Consider this:

def do_nothing(x):
pass

huge_tuple = (None,) * 10000**4
do_nothing(huge_tuple)

If Python made a copy of huge_tuple before passing itto > the function, you would notice.

Which succinctly demonstrates precisely why a newbie
*should* be told that Python passes references instead
of values.


"I don't like Chinese food, and pizza gives me gas. Let's
have a burger," says I.

And Terry helpfully answers: "Pizza gives you gas? Well
there you go then, that's precisely why we have to have
Chinese food."


An annoyingly banal, off-topic, and incorrect analogy.
I have never suggested that we should tell newbies that
Python is call by value, and I deny that the only two
possible choices for usefully describing Python's
behaviour is by CBV and CBR. The fact that Terry could
read this thread and still imagine that there is such a
dichotomy is worrying.
I didn't say you did, and it's very worrying that you could
read my post and not understand that. You want to get
tetchy? I can *be* tetchy, if that's what you want. ;-)

As far as I am concerned "call by object" which is what you
*did* propose implies "call by value" to anyone who is just
learning the language, and that is the audience we're
talking about.

I mean, *I* know what you mean when you say "Python is 'call
by object'" just as *you* know what I mean when I say
"Python is 'call by reference'", but where does that leave
Mr. Newbie?

Sorry, but the burgers give him gas, too.
But it should probably also be made clear that
"reference" means a label assigned to an object, and not
a variable containing a memory location (which is what a
C "pointer" is).

The reference is usually a simple name, but it can also
be an container expression following list, dictionary,
or class instance (spam, spam[0], spam['eggs'], or
spam.ham, for example). Not tuple or string because
they are immutable, and so don't have assignable
references.


Are you seriously suggesting that you can't include tuples
in a list, or pass them to functions? Because that's what
it sounds like you're saying: "Python passes references.
The reference is usually a simple name, but it can also be
a container... Not tuple or string because they are
immutable."

If you don't mean to say that Python can't pass strings to
functions, what do you mean to say?


No, don't be intentionally thick.

I mean that you cannot dereference a string or tuple in
order to assign elements of them -- which is another way of
saying they are immutable.
I'll tell you what I say: Python passes objects to
functions or assignments.

Does this mean that the object is copied? No, I didn't say
it copies objects. I left the nature of the passing
mechanism unspoken, which is how it should be because it
is an implementation detail.
And that is where we part ways, my friend. Because
"implementation details" do matter when they make a
difference between execution in 10 seconds and executions in
10 days. Even a newbie is going to be hesitant to do things
that look like they are going to do the latter. He still
needs to have a reasonably correct mental model of what his
program is going to do.
Does this mean that the object can be modified in place?
Certainly not, since that depends on the object, not on
the nature of Python's high-level behaviour. It emphasises
the object oriented nature of Python, and by its very
language warns the reader not to assume that Python
behaves identically to other languages. It invites further
questions, rather than lulling the reader into jumping to
false conclusions.
Chigaimasu! It just leads to *different* false conclusions.
The emphasis is on the *object*, not the passing
mechanism.[...]
In Python, whether or not you can change an object depends
on the object, not the language itself: it is a data
issue.


True, but the passing mechanism still makes a difference in
understanding how Python programs operate.

Of course, this conversation is starting to get extremely
silly.

Terry

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 7 '06 #56
Terry Hancock <ha*****@anansispaceworks.com> writes:
As far as I am concerned "call by object" which is what you
*did* propose implies "call by value" to anyone who is just
learning the language, and that is the audience we're
talking about.


From what I can tell, Liskov proposed *three* different names for
passing references to objects: call-by-sharing, call-by-object, and
call-by-object-reference.

Call by object is the worst choice among the three, because "object"
has such a vague meaning, so you never know what implications someone
will come away with. Of the other two, I like call by object
reference, because it's clear you're passing a reference to an object,
and it doesn't really matter what an object is in this case.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jan 7 '06 #57
Steven D'Aprano wrote:
On Thu, 05 Jan 2006 05:21:24 +0000, Bryan Olson wrote:

Steven D'Aprano wrote:
Mike Meyer wrote:
[...]
Correct. What's stored in a list is a reference.

Nonsense. What is stored in the list is an object.


According to the Python Language Reference:

Some objects contain references to other objects; these are
called containers. Examples of containers are tuples, lists
and dictionaries.
[http://docs.python.org/ref/objects.html]

Is it so hard to understand that the word "reference" has a general,
imprecise meaning in common English (which is clearly how the quote
above is using the word) while still having in the context of assignment
and argument passing a more precise meaning which is dangerously
misleading?


What's pretty easy to understand at this point, is that Mike
was right and you were wrong. "Reference" has a precise meaning
here, it's what the Python language uses, and contrary to your
reporting, it's what the rest of the discipline uses.
Words are important -- not only for what they mean, but for what the
connotations they carry. For people who come to Python from C-like
languages, the word "reference" means something that is just not true in
the context of Python's behaviour.
Wrong. C does not have references, and the Python use is consistent
with the rest of computer science. You seem to have read in things
that it does not mean. Fix *your* thinking.
That's why people come to Python with a frame that tells that what call by reference implies ("I can do this...")
and then they discover that they often *can't* do that.
I'm sorry if you got confused, but please don't project it on
the rest of the discipline. C does not have even references.

[...] Thinking about Python's behaviour ("it always passes references to
objects")
Just fix your thinking and don't attribute these problems to
others.

[...] If we were writing academic papers, we could define "call by reference"
and "objects contain references" any way we liked,


That would be a terrible thing to do. Just learn to use the
meaning accepted in the discipline, and used in the Python doc.

--
--Bryan
Jan 7 '06 #58
On Sat, 07 Jan 2006 01:29:46 -0500, Mike Meyer wrote:
Call by object is the worst choice among the three, because "object"
has such a vague meaning, so you never know what implications someone
will come away with.


So very unlike "call by reference", right?
--
Steven.

Jan 7 '06 #59
On Sat, 07 Jan 2006 11:20:25 +0000, Bryan Olson wrote:
Wrong. C does not have references, and the Python use is consistent
with the rest of computer science. You seem to have read in things
that it does not mean. Fix *your* thinking.


Bryan, I'll admit that I'm no C/C++ programmer, and I frequently assume
that if X is true for C++ it is also true for C, and vice versa. I
appreciate being corrected when I make a mistake.

However, in this case, I think you are confused by the term references. Of
course pure C does not have the C++ data structure known as "references",
but that is hardly the only meaning of the word. "Reference" is a generic
term for something which refers to something else, not just in plain
English but also in computer science. Pointers are references. Indexes
into a table are references. URLs are references. File names and file
handles are references, as are keys from databases, and even raw memory
addresses.

http://en.wikipedia.org/wiki/Referen...mputer_science)

I'll admit that my position on this question has changed. I no longer say
that "everything in Python is a reference" is *false*, not in the weak,
generic sense. How can it be? In the generic sense, Python names are
references. (Under the hood, names may even be implemented as C++
references for all I know.) I will still argue that the term reference is
harmful, not because it is technically incorrect, but because it activates
incorrect mental models of Python's high-level behaviour in too many
people.

That's why people come to Python with a
frame that tells that what call by reference implies ("I can do this...")
and then they discover that they often *can't* do that.


I'm sorry if you got confused, but please don't project it on
the rest of the discipline.


Perhaps you should check out the beginning of the thread before making
any additional comments. It wasn't me who was confused and asked "Hey
what's going on? I was told everything in Python is a reference, but when
I do this it doesn't work." I'm not projecting anything on anyone.
--
Steven.

Jan 7 '06 #60
Steven D'Aprano wrote:
Bryan Olson wrote:
Wrong. C does not have references, and the Python use is consistent
with the rest of computer science. You seem to have read in things
that it does not mean. Fix *your* thinking.

Bryan, I'll admit that I'm no C/C++ programmer, and I frequently assume
that if X is true for C++ it is also true for C, and vice versa. I
appreciate being corrected when I make a mistake.

However, in this case, I think you are confused by the term references.


No, though I should have had "references" in quotes; C doesn't
call anything a reference, so saying it confuses people about
what references are doesn't make sense.

[...] I'll admit that my position on this question has changed. I no longer say
that "everything in Python is a reference" is *false*, not in the weak,
generic sense.
Of course it's false. Is indentation a reference? Is a comment
a reference? The bad term there is "everything", not "reference".
How can it be? In the generic sense, Python names are
references. (Under the hood, names may even be implemented as C++
references for all I know.) I will still argue that the term reference is
harmful, not because it is technically incorrect, but because it activates
incorrect mental models of Python's high-level behaviour in too many
people.


Mike wrote that lists contain references. You said that was
nonsense as they contain objects. His description was right and
consistent with Python behavior. Yours was wrong and inconsistent
with Python behavior. List storing references is the *right*
mental model.

That's why people come to Python with a
frame that tells that what call by reference implies ("I can do this...")
and then they discover that they often *can't* do that.


I'm sorry if you got confused, but please don't project it on
the rest of the discipline.


Perhaps you should check out the beginning of the thread before making
any additional comments. It wasn't me who was confused and asked "Hey
what's going on? I was told everything in Python is a reference, but when
I do this it doesn't work." I'm not projecting anything on anyone.


Read more carefully. His problem was in understanding variable
assignment in C versus Python: storage in a location versus name
binding. He got some good explanations. Unfortunately there was
also quite a bit of wrong reporting, which some of us are trying
to correct.
--
--Bryan
Jan 7 '06 #61
Ben Sizer <ky*****@gmail.com> wrote:
...
assignment semantics that differ from languages such as C++ and Java,
not the calling mechanism. In C++, assignment means copying a value. In
Python, assignment means reassigning a reference.


And in Java, it means just the same as in Python (with some unfortunate
exceptions, in Java, for elementary types such as int -- but for all
normal types, the meaning of assignment and parameter passing is just
the same in Java as in Python).

Considering that Java may have become the language most used for first
courses in programming, it's unfortunate to propagate disinformation
about its assignment semantics differing from Python's -- it will
confuse people who know Java, and there are many of those.
Alex
Jan 7 '06 #62
Bryan Olson wrote:
Words are important -- not only for what they mean, but for what the
connotations they carry. For people who come to Python from C-like
languages, the word "reference" means something that is just not true in
the context of Python's behaviour.
Wrong. C does not have references


Unless they've changed it since the drafts, the ANSI C specification uses
the word "reference" to describe how pointers work:

A pointer type describes an object
whose value provides a reference to an entity of the
referenced type. A pointer type derived from the
referenced type T is sometimes called ``pointer to T''.
The construction of a pointer type from a referenced
type is called ``pointer type derivation''.

so unless you're using some odd dialect of C that doesn't support pointers,
your C implementation sure has references.
and the Python use is consistent with the rest of computer science.
The problem isn't the word "reference" in itself, the problem is when people
are implying that "since Python passes object references to functions, it's
using call by reference".

In ordinary CS, "call by reference" generally means that the function is
handed a reference to the *variable* holding the *value*. You can do
this explicitly in C (by passing in &arg instead of arg), and you can do
this in C++, but there's no way to do this in Python -- Python variables
hold objects, not values.

Saying that Python uses "call by value" is probably more correct (where
the values are references), but that's even more confusing. (see endless
earlier threads for more on this).
That would be a terrible thing to do. Just learn to use the
meaning accepted in the discipline, and used in the Python doc.


afaik, the Python Language Reference never defines the word "reference".

It carefully defines words like "object" and "value", though, and terms like
"call by object" or "call by object reference" are perfectly understandable
if you use the words as they are defined in the language reference.

</F>

Jan 7 '06 #63
On Sat, 07 Jan 2006 01:29:46 -0500
Mike Meyer <mw*@mired.org> wrote:
From what I can tell, Liskov proposed *three* different
names for
passing references to objects: call-by-sharing,
call-by-object, and call-by-object-reference.


"Call by object reference" makes the most sense to me. Names
in Python are object references: they refer to objects. You
might almost say "call by name" but that sort of implies
that you are passing the strings around (which is generally
untrue), and it doesn't convey what happens when the name is
something complex like "ham['spam'][0].eggs()[42]" (i.e.
"name" carries the conotation of being a simple string,
although you could argue that it doesn't have to mean that).

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Jan 7 '06 #64
Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:
On Sat, 07 Jan 2006 01:29:46 -0500, Mike Meyer wrote:
Call by object is the worst choice among the three, because "object"
has such a vague meaning, so you never know what implications someone
will come away with.

So very unlike "call by reference", right?


Right. All references are objects, so "call by object" includes all
the possibilities of "call by reference" as a subset. Not all objects
are references, so "call by reference", so it's a proper subset.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jan 7 '06 #65
"Fredrik Lundh" <fr*****@pythonware.com> writes:
In ordinary CS, "call by reference" generally means that the function is
handed a reference to the *variable* holding the *value*.
That's the strictest definition of "call-by-reference". It's got a
major problem in that it means doing (with C syntax) "foo(&l[23])"
isn't CBR, because I didn't pass a reference to a *variable*. For
Python to be CBR, you have to use a broad definition of CBR
Saying that Python uses "call by value" is probably more correct (where
the values are references), but that's even more confusing.


I wouldn't say 'more correct', because of the above. But since *all*
paramater passing mechanisms pass a value of some kind - even
call-by-substitution - they're all call by value with that
definition. That makes the phrase pretty much useless.

The problem is that CBR and CBV were defined for langauges with
variables that had addresses, and assignments that copied values into
those addresses. The definitions were stretched by various groups to
fit their language, and some of the definitions disagree about edge
cases. The calling mechanisms of languages that have variables that
are bound to objects are all edge cases.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jan 7 '06 #66
Terry Hancock <ha*****@anansispaceworks.com> writes:
On Sat, 07 Jan 2006 01:29:46 -0500
Mike Meyer <mw*@mired.org> wrote:
From what I can tell, Liskov proposed *three* different
names for
passing references to objects: call-by-sharing,
call-by-object, and call-by-object-reference.

"Call by object reference" makes the most sense to me. Names
in Python are object references: they refer to objects. You
might almost say "call by name" but that sort of implies
that you are passing the strings around (which is generally
untrue)


"Call by name" has a specific meaning that is different from passing
strings around. CBName (and CBNeed) is generally implemented by
passing thunks. In Python, you could do CBN by passing tuples of
(string, globals(), locals()) around - which probably makes enough
noise when it hits the stack to qualify as a thunk.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jan 7 '06 #67
[contextectomy, because this quote makes no sense with or without
context]

In article <86************@bhuda.mired.org>, Mike Meyer <mw*@mired.org> wrote:

Right. All references are objects, so "call by object" includes all
the possibilities of "call by reference" as a subset. Not all objects
are references, so "call by reference", so it's a proper subset.


Wrong. All references are *to* objects, maybe. There are no objects
that "are" references -- objects may *contain* references. You're
losing sight of the fact that objects and references are really two
completely different things in Python.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"19. A language that doesn't affect the way you think about programming,
is not worth knowing." --Alan Perlis
Jan 7 '06 #68
In article <ma**************************************@python.o rg>,
Fredrik Lundh <fr*****@pythonware.com> wrote:
and the Python use is consistent with the rest of computer science.


The problem isn't the word "reference" in itself, the problem is when people
are implying that "since Python passes object references to functions, it's
using call by reference".


Actually, I think the problem is not in the "call" bit. Python behaves
more or less like all other call by reference languages in the call. What
is confusing people is what happens when you *assign* to a function argument.

Those confused are expecting Python function arguments to behave just
like C++ references (which are just syntactic sugar for a dereferenced
pointer) or an Ada "in out" parameter when assigned. Python doesn't,
because in Python assignment assigns a new reference to the name,
rather than changing the referenced object.

/Anders
--
-- Of course I'm crazy, but that doesn't mean I'm wrong.
Anders Hammarquist | ik*@cd.chalmers.se
Physics student, Chalmers University of Technology, | Hem: +46 31 88 48 50
G|teborg, Sweden. RADIO: SM6XMM and N2JGL | Mob: +46 707 27 86 87
Jan 8 '06 #69

Fredrik Lundh wrote:
....snip...
afaik, the Python Language Reference never defines the word "reference".
It carefully defines words like "object" and "value", though, and terms like
"call by object" or "call by object reference" are perfectly understandable
if you use the words as they are defined in the language reference.


It (sec. 3.1, "Objects, values and types") is not what I would
call a good definition . About values it says only

- that they are something that all objects have.
- they can be mutable or immutable.

It then has a few sentences about mutability, so after reading
it you will know that, whatever a value is, it can be changed
for some objects but not others. But what exactly it is that is
being changed is still a mystery.
Further down it talks about container objects "containing"
references to other objects and of those being part of it's
value. Part? What does it mean to contain? Can one
determine from reading this, if an attribute value is part
of the object's value? (I couldn't).

On my list on Python Doc problems that need fixing, is
"defintion of object values" and it has been on there
for nearly a year.

So I don't think referring people to the Language Reference
is a good way to help them understand Python. Python
badly needs a rewritten Language Reference.

Jan 9 '06 #70
Quoth ru***@yahoo.com:
| Fredrik Lundh wrote:
| ...snip...
| > afaik, the Python Language Reference never defines the word "reference".
| > It carefully defines words like "object" and "value", though, and terms like
| > "call by object" or "call by object reference" are perfectly understandable
| > if you use the words as they are defined in the language reference.
|
| It (sec. 3.1, "Objects, values and types") is not what I would
| call a good definition . About values it says only
|
| - that they are something that all objects have.
| - they can be mutable or immutable.
|
| It then has a few sentences about mutability, so after reading
| it you will know that, whatever a value is, it can be changed
| for some objects but not others. But what exactly it is that is
| being changed is still a mystery.
| Further down it talks about container objects "containing"
| references to other objects and of those being part of it's
| value. Part? What does it mean to contain? Can one
| determine from reading this, if an attribute value is part
| of the object's value? (I couldn't).
|
| On my list on Python Doc problems that need fixing, is
| "defintion of object values" and it has been on there
| for nearly a year.

So you've had time to think about how you would define value, in a
few words. Any ideas?

I find the topic difficult, myself. I think you really have to apply
some context to the question, so there may not be any satisfactory
definition for the language reference.

But maybe it would be simple with the right focus. If we could somehow
define value, how would that help? I mean, presumably we need to
understand all this stuff because we want to write some software, and
if we dive in without understanding, our attempts will be plagued with
conceptual errors. Is there something about value in particular that
seems to be a problem here? ``No, you idiot, that's not a value -
THIS is a value!''

Donn Cave, do**@drizzle.com
Jan 9 '06 #71
Mike Meyer wrote:
This is where we disagree. I think their understanding of references
is dead on. What's broken is their understanding of what variables are
and what assignments mean. Once you fix that, the rest falls into
place.

(Steven D'Aprano wrote:)
The fact that call by object is unfamiliar is precisely its advantage.
Instead of people jumping to conclusions about what it means, like they do
with "reference", they will stop and think and if need be look for further
information about Python's object model. At the very least, they won't say
"Everything in Python is a reference, so this should work, but it
doesn't".


What you're advocating is intentionally misleading people to deal with
a symptom. I'd rather give them enough truth to deal with the disease.


I agree completely. I have personally "converted" around a half-dozen
or so coworkers to Python over the course of the last three or four
years. The conversion takes place in stages. Usually, I have written
a small script for them which they later want to enhance, so they come
to me for a tutorial session.

My initial 5-10 minute tutorial starts off with an explanation of
name-binding, including something like "a=[1,2,3]; b=a; a[1]=4; print
b; b=42; print a, b". Note that this also demonstrates the dynamic
nature of Python typing -- 'b' is not restricted to being bound to a
list merely because the first time it was bound was to a list.

Once they have that down, I describe "immutable" vs. "mutable". I
start off by explaining that of course integers are immutable because
you cannot change 1 into 5. I then explain (with examples) that,
additionally, in the language, strings are immutable (which does NOT
mean you cannot usefully manipulate them, just that, for example, in "x
= 'abc'; x = x + 'd'" the manipulation "x + 'd'" results in a
completely new string. (The attempted example x[1] = "d" also gets them
used to the exception reporting mechanism.)

I actually spend more time (of this 10 minutes!) on "immutable" vs.
"mutable" (including ancillary lessons) than I spend on anything else.
After showing that strings are immutable, I then explain that tuples
are a sort of immutable list. This usually elicits the question of why
such a thing is needed, which is a great segue into a minute or so
spent on dictionaries and their keys. (Dictionaries can occupy
additional time if the student recognizes that they are a good fit for
a pressing need.)

Only about the last 30 seconds or so is spent on function calling. I
explain that all parameters are passed by reference, but that
OBVIOUSLY, if the called function wants to alter the caller's object,
the referenced object must be mutable, because, JUST AS WITH C
POINTERS, the pointer to the object is passed by making a copy of it on
the stack, so there is no way that the callee can directly alter the
caller's own pointer to the object.

After this lesson, I send them back to look at their script with
information about the online docs and a standing offer to help them
over any rough spots. NOT ONE PERSON has ever been confused about the
parameter passing.

I have only given these tutorials to accomplished programmers, so my
opinion about teaching newbies is not as well-formed, but for a
C/C++/assembler programmer, the REAL question about parameters is "What
is pushed onto the stack?" They are capable of a high level of
abstraction, so all they really want to know "Is a COPY of the object
passed on the stack, or is a POINTER to the object passed on the
stack?"

With such an accomplished student, if the teacher described Python's
parameter passing as anything but "call by reference", it would lead
to confusion, and, ultimately, disrespect for the teacher.

Regards,
Pat

Jan 9 '06 #72
Mike Meyer wrote:
This is where we disagree. I think their understanding of references
is dead on. What's broken is their understanding of what variables are
and what assignments mean. Once you fix that, the rest falls into
place.

(Steven D'Aprano wrote:)
The fact that call by object is unfamiliar is precisely its advantage.
Instead of people jumping to conclusions about what it means, like they do
with "reference", they will stop and think and if need be look for further
information about Python's object model. At the very least, they won't say
"Everything in Python is a reference, so this should work, but it
doesn't".


What you're advocating is intentionally misleading people to deal with
a symptom. I'd rather give them enough truth to deal with the disease.


I agree completely. I have personally "converted" around a half-dozen
or so coworkers to Python over the course of the last three or four
years. The conversion takes place in stages. Usually, I have written
a small script for them which they later want to enhance, so they come
to me for a tutorial session.

My initial 5-10 minute tutorial starts off with an explanation of
name-binding, including something like "a=[1,2,3]; b=a; a[1]=4; print
b; b=42; print a, b". Note that this also demonstrates the dynamic
nature of Python typing -- 'b' is not restricted to being bound to a
list merely because the first time it was bound was to a list.

Once they have that down, I describe "immutable" vs. "mutable". I
start off by explaining that of course integers are immutable because
you cannot change 1 into 5. I then explain (with examples) that,
additionally, in the language, strings are immutable (which does NOT
mean you cannot usefully manipulate them, just that, for example, in "x
= 'abc'; x = x + 'd'" the manipulation "x + 'd'" results in a
completely new string. (The attempted example x[1] = "d" also gets them
used to the exception reporting mechanism.)

I actually spend more time (of this 10 minutes!) on "immutable" vs.
"mutable" (including ancillary lessons) than I spend on anything else.
After showing that strings are immutable, I then explain that tuples
are a sort of immutable list. This usually elicits the question of why
such a thing is needed, which is a great segue into a minute or so
spent on dictionaries and their keys. (Dictionaries can occupy
additional time if the student recognizes that they are a good fit for
a pressing need.)

Only about the last 30 seconds or so is spent on function calling. I
explain that all parameters are passed by reference, but that
OBVIOUSLY, if the called function wants to alter the caller's object,
the referenced object must be mutable, because, JUST AS WITH C
POINTERS, the pointer to the object is passed by making a copy of it on
the stack, so there is no way that the callee can directly alter the
caller's own pointer to the object.

After this lesson, I send them back to look at their script with
information about the online docs and a standing offer to help them
over any rough spots. NOT ONE PERSON has ever been confused about the
parameter passing.

I have only given these tutorials to accomplished programmers, so my
opinion about teaching newbies is not as well-formed, but for a
C/C++/assembler programmer, the REAL question about parameters is "What
is pushed onto the stack?" They are capable of a high level of
abstraction, so all they really want to know "Is a COPY of the object
passed on the stack, or is a POINTER to the object passed on the
stack?"

With such an accomplished student, if the teacher described Python's
parameter passing as anything but "call by reference", it would lead
to confusion, and, ultimately, disrespect for the teacher.

Regards,
Pat

Jan 9 '06 #73
Mike Meyer wrote:
This is where we disagree. I think their understanding of references
is dead on. What's broken is their understanding of what variables are
and what assignments mean. Once you fix that, the rest falls into
place.

(Steven D'Aprano wrote:)
The fact that call by object is unfamiliar is precisely its advantage.
Instead of people jumping to conclusions about what it means, like they do
with "reference", they will stop and think and if need be look for further
information about Python's object model. At the very least, they won't say
"Everything in Python is a reference, so this should work, but it
doesn't".


What you're advocating is intentionally misleading people to deal with
a symptom. I'd rather give them enough truth to deal with the disease.


I agree completely. I have personally "converted" around a half-dozen
or so coworkers to Python over the course of the last three or four
years. The conversion takes place in stages. Usually, I have written
a small script for them which they later want to enhance, so they come
to me for a tutorial session.

My initial 5-10 minute tutorial starts off with an explanation of
name-binding, including something like "a=[1,2,3]; b=a; a[1]=4; print
b; b=42; print a, b". Note that this also demonstrates the dynamic
nature of Python typing -- 'b' is not restricted to being bound to a
list merely because the first time it was bound was to a list.

Once they have that down, I describe "immutable" vs. "mutable". I
start off by explaining that of course integers are immutable because
you cannot change 1 into 5. I then explain (with examples) that,
additionally, in the language, strings are immutable (which does NOT
mean you cannot usefully manipulate them, just that, for example, in "x
= 'abc'; x = x + 'd'" the manipulation "x + 'd'" results in a
completely new string. (The attempted example x[1] = "d" also gets them
used to the exception reporting mechanism.)

I actually spend more time (of this 10 minutes!) on "immutable" vs.
"mutable" (including ancillary lessons) than I spend on anything else.
After showing that strings are immutable, I then explain that tuples
are a sort of immutable list. This usually elicits the question of why
such a thing is needed, which is a great segue into a minute or so
spent on dictionaries and their keys. (Dictionaries can occupy
additional time if the student recognizes that they are a good fit for
a pressing need.)

Only about the last 30 seconds or so is spent on function calling. I
explain that all parameters are passed by reference, but that
OBVIOUSLY, if the called function wants to alter the caller's object,
the referenced object must be mutable, because, JUST AS WITH C
POINTERS, the pointer to the object is passed by making a copy of it on
the stack, so there is no way that the callee can directly alter the
caller's own pointer to the object.

After this lesson, I send them back to look at their script with
information about the online docs and a standing offer to help them
over any rough spots. NOT ONE PERSON has ever been confused about the
parameter passing.

I have only given these tutorials to accomplished programmers, so my
opinion about teaching newbies is not as well-formed, but for a
C/C++/assembler programmer, the REAL question about parameters is "What
is pushed onto the stack?" They are capable of a high level of
abstraction, so all they really want to know "Is a COPY of the object
passed on the stack, or is a POINTER to the object passed on the
stack?"

With such an accomplished student, if the teacher described Python's
parameter passing as anything but "call by reference", it would lead
to confusion, and, ultimately, disrespect for the teacher.

Regards,
Pat

Jan 9 '06 #74
Mike Meyer wrote:
This is where we disagree. I think their understanding of references
is dead on. What's broken is their understanding of what variables are
and what assignments mean. Once you fix that, the rest falls into
place.

(Steven D'Aprano wrote:)
The fact that call by object is unfamiliar is precisely its advantage.
Instead of people jumping to conclusions about what it means, like they do
with "reference", they will stop and think and if need be look for further
information about Python's object model. At the very least, they won't say
"Everything in Python is a reference, so this should work, but it
doesn't".


What you're advocating is intentionally misleading people to deal with
a symptom. I'd rather give them enough truth to deal with the disease.


I agree completely. I have personally "converted" around a half-dozen
or so coworkers to Python over the course of the last three or four
years. The conversion takes place in stages. Usually, I have written
a small script for them which they later want to enhance, so they come
to me for a tutorial session.

My initial 5-10 minute tutorial starts off with an explanation of
name-binding, including something like "a=[1,2,3]; b=a; a[1]=4; print
b; b=42; print a, b". Note that this also demonstrates the dynamic
nature of Python typing -- 'b' is not restricted to being bound to a
list merely because the first time it was bound was to a list.

Once they have that down, I describe "immutable" vs. "mutable". I
start off by explaining that of course integers are immutable because
you cannot change 1 into 5. I then explain (with examples) that,
additionally, in the language, strings are immutable (which does NOT
mean you cannot usefully manipulate them, just that, for example, in "x
= 'abc'; x = x + 'd'" the manipulation "x + 'd'" results in a
completely new string. (The attempted example x[1] = "d" also gets them
used to the exception reporting mechanism.)

I actually spend more time (of this 10 minutes!) on "immutable" vs.
"mutable" (including ancillary lessons) than I spend on anything else.
After showing that strings are immutable, I then explain that tuples
are a sort of immutable list. This usually elicits the question of why
such a thing is needed, which is a great segue into a minute or so
spent on dictionaries and their keys. (Dictionaries can occupy
additional time if the student recognizes that they are a good fit for
a pressing need.)

Only about the last 30 seconds or so is spent on function calling. I
explain that all parameters are passed by reference, but that
OBVIOUSLY, if the called function wants to alter the caller's object,
the referenced object must be mutable, because, JUST AS WITH C
POINTERS, the pointer to the object is passed by making a copy of it on
the stack, so there is no way that the callee can directly alter the
caller's own pointer to the object.

After this lesson, I send them back to look at their script with
information about the online docs and a standing offer to help them
over any rough spots. NOT ONE PERSON has ever been confused about the
parameter passing.

I have only given these tutorials to accomplished programmers, so my
opinion about teaching newbies is not as well-formed, but for a
C/C++/assembler programmer, the REAL question about parameters is "What
is pushed onto the stack?" They are capable of a high level of
abstraction, so all they really want to know "Is a COPY of the object
passed on the stack, or is a POINTER to the object passed on the
stack?"

With such an accomplished student, if the teacher described Python's
parameter passing as anything but "call by reference", it would lead
to confusion, and, ultimately, disrespect for the teacher.

Regards,
Pat

Jan 9 '06 #75

"Fredrik Lundh" <fr*****@pythonware.com> wrote:
....snip...
afaik, the Python Language Reference never defines the word "reference".

It carefully defines words like "object" and "value", though, and terms like
"call by object" or "call by object reference" are perfectly understandable
if you use the words as they are defined in the language reference.


The Language Reference's definition of "value" is a non-definition.
About "value" it says that it is one of the three things an object
has. It then says some values can change and talks about
mutable and immutable. But we don't know what *it* is that
is mutable or immutable (other that it's called a "value" and it
is something an object "has").

Further down the page it says that container objects may have
references that are part of it's value. Part? Which part? Part
of what? Is an attribute part of a value?

I started a list of python doc problems a while ago. Right
near the top is "object value defintion is useless".

As I've said before, the Language Reference is badly
broken and needs a major rewrite. I don't think it should
be recommended to anyone as a source of authorative
information (except possibly for syntax since it in mostly
a Syntax Reference right now.)

[I posted another version of this yesterday from Google
but it has not appeared so...]

Jan 9 '06 #76
Op 2006-01-06, Steven D'Aprano schreef <st***@REMOVETHIScyber.com.au>:
If we say "Python is call be reference" (or call by value, as many people
also say) we *know* the consequence will be newbies writing in saying "I
was told Python is call by reference, so I did this, and it didn't work,
is that a bug in Python? What is wrong?" It is not a bug in Python, it is
a bug in their mental model of how Python works, and we put that bug in
their head. Every time that happens, it is *our* fault, not theirs, for
using language guaranteed to mislead.


Well then I would think that the language that misleads is not
"reference" but assignment. Because it is not their idea of
call by reference that leads to the misconception, but their
idea of what an assignment does.

--
Antoon Pardon
Jan 9 '06 #77

"Donn Cave" <do**@drizzle.com> wrote in message
news:11***************@jetspin.drizzle.com...
Quoth ru***@yahoo.com:
| Fredrik Lundh wrote:
| ...snip...
| > afaik, the Python Language Reference never defines the word "reference".
| > It carefully defines words like "object" and "value", though, and terms like
| > "call by object" or "call by object reference" are perfectly understandable
| > if you use the words as they are defined in the language reference.
|
| It (sec. 3.1, "Objects, values and types") is not what I would
| call a good definition . About values it says only
|
| - that they are something that all objects have.
| - they can be mutable or immutable.
|
| It then has a few sentences about mutability, so after reading
| it you will know that, whatever a value is, it can be changed
| for some objects but not others. But what exactly it is that is
| being changed is still a mystery.
| Further down it talks about container objects "containing"
| references to other objects and of those being part of it's
| value. Part? What does it mean to contain? Can one
| determine from reading this, if an attribute value is part
| of the object's value? (I couldn't).
|
| On my list on Python Doc problems that need fixing, is
| "defintion of object values" and it has been on there
| for nearly a year.

So you've had time to think about how you would define value, in a
few words. Any ideas?
Not yet. The reason is that I am still trying to figure out
what a value is myself. Do all objects have values? If
not which do and which don't? What's the value of int(1)?
An object? Some otherwise unreachable thing that
represents the abstract concept of the number 1?
What the value of object()? A few weeks ago I turned
to that page for enlightenment, with the results I reported.
I find the topic difficult, myself. I think you really have to apply
some context to the question, so there may not be any satisfactory
definition for the language reference.
I have a hard time accepting that. I do not think there
is any aspect of human thought that cannot be described
by a sufficiently skilled writer.
But maybe it would be simple with the right focus. If we could somehow
define value, how would that help? I mean, presumably we need to
understand all this stuff because we want to write some software, and
if we dive in without understanding, our attempts will be plagued with
conceptual errors. Is there something about value in particular that
seems to be a problem here? ``No, you idiot, that's not a value -
THIS is a value!''


Yes, see above. How can you feel confident working with
things that aren't understood? (c.f. this thead about
problems resulting from python beginner's misconceptions
about references.)

Jan 10 '06 #78
On Mon, 09 Jan 2006 07:40:18 -0000, "Donn Cave" <do**@drizzle.com> wrote:
Quoth ru***@yahoo.com:
| Fredrik Lundh wrote:
| ...snip...
| > afaik, the Python Language Reference never defines the word "reference".
| > It carefully defines words like "object" and "value", though, and terms like
| > "call by object" or "call by object reference" are perfectly understandable
| > if you use the words as they are defined in the language reference.
|
| It (sec. 3.1, "Objects, values and types") is not what I would
| call a good definition . About values it says only
|
| - that they are something that all objects have.
| - they can be mutable or immutable.
|
| It then has a few sentences about mutability, so after reading
| it you will know that, whatever a value is, it can be changed
| for some objects but not others. But what exactly it is that is
| being changed is still a mystery.
| Further down it talks about container objects "containing"
| references to other objects and of those being part of it's
| value. Part? What does it mean to contain? Can one
| determine from reading this, if an attribute value is part
| of the object's value? (I couldn't).
|
| On my list on Python Doc problems that need fixing, is
| "defintion of object values" and it has been on there
| for nearly a year.

So you've had time to think about how you would define value, in a
few words. Any ideas?

I find the topic difficult, myself. I think you really have to apply
some context to the question, so there may not be any satisfactory
definition for the language reference.

But maybe it would be simple with the right focus. If we could somehow
define value, how would that help? I mean, presumably we need to
understand all this stuff because we want to write some software, and
if we dive in without understanding, our attempts will be plagued with
conceptual errors. Is there something about value in particular that
seems to be a problem here? ``No, you idiot, that's not a value -
THIS is a value!''

IMO the problem is that our intuitive notion of value is ususally really of
an abstract value, like an integer value or a real or maybe a member of a finite
abstract set. But in programming we are always dealing with various concrete
representations of values, not values themselves. To get to a value, you have
to interpret the representation. To perform abstract operations, you have to
manipulate concrete representations, and guarantee that the resulting representations
really do represent the abstract results of the abstract operation.

People are so used to interpreting representations that they do it unconsciously.
Mostly the metonymic use of representations in discussing abstractions is a
taken-for-granted short cut for avoiding tiresome pedantry, but sometimes, I believe,
it lies at the heart of difficulties such as in trying to define value.

IMO the first step in defining "value" should be to declare that it always refers
to some abstract value, which is always an interpretation of some concrete representation.

I suspect that describing things in terms of abstract graphs and their transformations
would be useful. E.g., starting with python's objects (in the abstract) as nodes,
and "references" as directed arcs.

More on this later, perhaps, but I have to go now ...

Regards,
Bengt Richter
Jan 10 '06 #79

Alex Martelli wrote:
Ben Sizer <ky*****@gmail.com> wrote:
...
assignment semantics that differ from languages such as C++ and Java,
not the calling mechanism. In C++, assignment means copying a value. In
Python, assignment means reassigning a reference.


And in Java, it means just the same as in Python (with some unfortunate
exceptions, in Java, for elementary types such as int -- but for all
normal types, the meaning of assignment and parameter passing is just
the same in Java as in Python).

Considering that Java may have become the language most used for first
courses in programming, it's unfortunate to propagate disinformation
about its assignment semantics differing from Python's -- it will
confuse people who know Java, and there are many of those.


Yes, my mistake - I forgot that Java reseats object references rather
than copying object values. (I'm a C++ person at heart.)

Personally I think this is a reason why Java is a poor language to
teach beginners, as it's stuck between low level semantics from C and
high level semantics like those of Python. It doesn't provide a very
consistent view, meaning you're bound to get confused no matter what
second language you start to learn.

--
Ben Sizer

Jan 10 '06 #80
ru***@yahoo.com wrote:
afaik, the Python Language Reference never defines the word "reference".
It carefully defines words like "object" and "value", though, and terms like
"call by object" or "call by object reference" are perfectly understandable
if you use the words as they are defined in the language reference.


It (sec. 3.1, "Objects, values and types") is not what I would
call a good definition . About values it says only

- that they are something that all objects have.
- they can be mutable or immutable.

It then has a few sentences about mutability, so after reading
it you will know that, whatever a value is, it can be changed
for some objects but not others. But what exactly it is that is
being changed is still a mystery.


you really have trouble with abstract concepts, don't you?

*what* the value is is defined by the operations that the object supports (via its
type).

*how* the value is represented inside the object is completely irrelevant; a Python
implementation may use electric charges in small capacitors, piles of rocks, diapers,
or an endless supply of small guys in odd costumes to encode the value inside an
object. Changes to the value may be carried out by CPU instructions, caterpillars,
toddlers with gasmasks, or an endless supply of small guys in odd costumes. The
only thing that's important is that you can, in your Python program, access an ob-
jects value via its type, and get other objects back when you do.

</F>

Jan 10 '06 #81
In article <11**********************@o13g2000cwo.googlegroups .com>,
ru***@yahoo.com wrote:
"Donn Cave" <do**@drizzle.com> wrote in message
news:11***************@jetspin.drizzle.com...

....
So you've had time to think about how you would define value, in a
few words. Any ideas?


Not yet. The reason is that I am still trying to figure out
what a value is myself. Do all objects have values? If
not which do and which don't? What's the value of int(1)?
An object? Some otherwise unreachable thing that
represents the abstract concept of the number 1?
What the value of object()? A few weeks ago I turned
to that page for enlightenment, with the results I reported.
I find the topic difficult, myself. I think you really have to apply
some context to the question, so there may not be any satisfactory
definition for the language reference.


I have a hard time accepting that. I do not think there
is any aspect of human thought that cannot be described
by a sufficiently skilled writer.


But you're asking for more than that. We're not just talking
about how people think about value, you want a definition that's
suitable for a language reference. Whereupon you would indeed
run into the kinds of questions you pose above, and more.
But maybe it would be simple with the right focus. If we could somehow
define value, how would that help? I mean, presumably we need to
understand all this stuff because we want to write some software, and
if we dive in without understanding, our attempts will be plagued with
conceptual errors. Is there something about value in particular that
seems to be a problem here? ``No, you idiot, that's not a value -
THIS is a value!''


Yes, see above. How can you feel confident working with
things that aren't understood? (c.f. this thead about
problems resulting from python beginner's misconceptions
about references.)


I'm saying that the definition of value doesn't contribute to
my understanding of my work. I guess we might say that the
whole point of a computer programming language is a mechanism
for the representation and manipulation of values, and our
task is to understand the mechanism enough to work with it.
That's what the language reference is for.

Donn Cave, do**@u.washington.edu
Jan 10 '06 #82
Donn Cave <do**@u.washington.edu> writes:
But you're asking for more than that. We're not just talking
about how people think about value, you want a definition that's
suitable for a language reference. Whereupon you would indeed
run into the kinds of questions you pose above, and more.


I know the Scheme standard includes a formal mathematical description
of the language semantics, maybe because the felt the usual verbiage
couldn't be precise enough.
Jan 10 '06 #83

"Fredrik Lundh" <fr*****@pythonware.com> wrote in message
news:ma**************************************@pyth on.org...
ru***@yahoo.com wrote:
afaik, the Python Language Reference never defines the word "reference".
It carefully defines words like "object" and "value", though, and terms like
"call by object" or "call by object reference" are perfectly understandable
if you use the words as they are defined in the language reference.
It (sec. 3.1, "Objects, values and types") is not what I would
call a good definition . About values it says only

- that they are something that all objects have.
- they can be mutable or immutable.

It then has a few sentences about mutability, so after reading
it you will know that, whatever a value is, it can be changed
for some objects but not others. But what exactly it is that is
being changed is still a mystery.


you really have trouble with abstract concepts, don't you?


Usually not when they are explained well.
*what* the value is is defined by the operations that the object supports (via its
type).
Well, that is already better than what is in the Lang Ref.
But there must be more to it than that. int(1) and int(2)
have exactly the same operations, yes? Yet their values
are different. (By "operations" you mean the set of methods
an object has?)

This interest is not just idle mental calesthenics.
I wanted to write a function that would dump the contents
of any object (value and attributes), and got rather confused
about values, types, repr's, etc.

It would help if you or someone would answer these
five questions (with something more than "yes" or "no" :-)

1. Do all objects have values?
2. What is the value of object()?
3. If two objects are equal with "==", does that
mean their values are the same?
4. Are object attributes part of an object's type
or it's value, or something else? (I think the first.)
5. The (only?) way to get an object's value is to
evaluate something (a name or a "reference"(*)
that refers to the object.

(*) I did not go back through this whole thread
but I know "reference" is controversial. I am not
trying to revive that debate. I mean the word in
a very generic sense.
*how* the value is represented inside the object is completely irrelevant;

....snip...
Yes, I agree and did not intend to imply otherwise.

Jan 13 '06 #84

"Donn Cave" <do**@u.washington.edu> wrote:
In article <11**********************@o13g2000cwo.googlegroups .com>,
ru***@yahoo.com wrote:
"Donn Cave" <do**@drizzle.com> wrote in message
news:11***************@jetspin.drizzle.com...

...
So you've had time to think about how you would define value, in a
few words. Any ideas?


Not yet. The reason is that I am still trying to figure out
what a value is myself. Do all objects have values? If
not which do and which don't? What's the value of int(1)?
An object? Some otherwise unreachable thing that
represents the abstract concept of the number 1?
What the value of object()? A few weeks ago I turned
to that page for enlightenment, with the results I reported.
I find the topic difficult, myself. I think you really have to apply
some context to the question, so there may not be any satisfactory
definition for the language reference.


I have a hard time accepting that. I do not think there
is any aspect of human thought that cannot be described
by a sufficiently skilled writer.


But you're asking for more than that. We're not just talking
about how people think about value, you want a definition that's
suitable for a language reference. Whereupon you would indeed
run into the kinds of questions you pose above, and more.
But maybe it would be simple with the right focus. If we could somehow
define value, how would that help? I mean, presumably we need to
understand all this stuff because we want to write some software, and
if we dive in without understanding, our attempts will be plagued with
conceptual errors. Is there something about value in particular that
seems to be a problem here? ``No, you idiot, that's not a value -
THIS is a value!''


Yes, see above. How can you feel confident working with
things that aren't understood? (c.f. this thead about
problems resulting from python beginner's misconceptions
about references.)


I'm saying that the definition of value doesn't contribute to
my understanding of my work. I guess we might say that the
whole point of a computer programming language is a mechanism
for the representation and manipulation of values, and our
task is to understand the mechanism enough to work with it.
That's what the language reference is for.


I think the difference in our perspectives is that you already
*know* what a value is, not necessarily in a way that allows
you to write a defintion, but certainly in a way that allows
to work effectively with them.

As a Python beginner, I do not know, and I need something
more than "it is something an object has". I do NOT need
eiher some formal specifcation, nor a metaphysical discussion
that relates it to platonic ideals and other such concepts.

Surely there is some middle ground?

Jan 13 '06 #85
ru***@yahoo.com schrieb:
"Fredrik Lundh" <fr*****@pythonware.com> wrote in message
*what* the value is is defined by the operations that the object supports (via its
type).
Well, that is already better than what is in the Lang Ref.
But there must be more to it than that. int(1) and int(2)
have exactly the same operations, yes? Yet their values
are different. (By "operations" you mean the set of methods
an object has?)


well, yes, but the behavior of the operations of an object are
based on its value. and in python you have no other possibility
to get closer to an objects value than to look what its methods
do (in the case of an int, print it, compare it, etc.). that
means the whole concept of a value is not really necessary to be
able to write a python program.
1. Do all objects have values?
2. What is the value of object()?
i'd say these two are closely related, and i'd say yes, all objects
have values and you can't really tell what the value of an object() is.
what you can say is, that two object()s have different values, because
their behavior differs (id(object)!).

but, one could define that id() is a special case and does not
contribute to the behavior of an object, so that different int
objects that print the same really have the same value.
3. If two objects are equal with "==", does that
mean their values are the same?
no, absolutely not. think this class:

class C(object):
def __eq__(self, other):
return True
4. Are object attributes part of an object's type
or it's value, or something else? (I think the first.)
they are part of an objects operations, just a shorthand for
__getattr__ and __setattr__.
5. The (only?) way to get an object's value is to
evaluate something (a name or a "reference"(*)
that refers to the object.


there is no such way (at least not to my knowledge).
at least not in general. of course you can print an int
and "see" its value, but you could define a C extension type
which holds a whole bunch of things as its value that are
completely inaccessible from python (are they then even part
of such an objects value? i don't care, its no use to define
"value" in either way).

i hope i did not confuse more than clarify, but this is the way
i see it.

also note that i understood Fredrik's quote from above in exactly
this way, this is just meant to clarify. (so please correct me if
i'm wrong)

--
David.
Jan 13 '06 #86
ru***@yahoo.com wrote:
"Fredrik Lundh" <fr*****@pythonware.com> wrote in message [...]

you really have trouble with abstract concepts, don't you?

Usually not when they are explained well.

You want to be careful - the bot will get you! Don't be rude to the bot!
*what* the value is is defined by the operations that the object supports (via its
type).

Well, that is already better than what is in the Lang Ref.
But there must be more to it than that. int(1) and int(2)
have exactly the same operations, yes? Yet their values
are different. (By "operations" you mean the set of methods
an object has?)

He does. But "the value of an object" is a bit like saying "the value of
a car": a car is a complex object, with properties (number of doors, for
example, which can differ from car to car) and operations (like "start
engine", "accelerate", "brake" and so on).
This interest is not just idle mental calesthenics.
I wanted to write a function that would dump the contents
of any object (value and attributes), and got rather confused
about values, types, repr's, etc.
Well it's an ambitious project, but not an impossible one. Python has
features for "introspection", which means that programs can examine the
structure of the data rather than only dealing with values of known
structure.
It would help if you or someone would answer these
five questions (with something more than "yes" or "no" :-)
Well I've been staying away from this thread, but I'll try. For
demagogic purposes I am omitting consideration of what are usually
called "classic classes". You can talk about them once you understand
the situation in more detail.

Note to nitpickers
------------------
Please note that I *am* oversimplifying here, and the nitpickers will
undoubtedly find many threadsworth of valuable material here. The point
is to develop an understanding of the *principles*. Once someone has
that they can pick up the details as they need them, which 98% of Python
users don't feel the need to. I don't even claim to know the whole
story, but I *do* know enough to explain it in principle. So by all
means correct me where I am demonstrably wring, but *please* don't just
add complexity that doesn't aid understanding.

So sit comfortably, and we'll learn about object-oriented systems.
1. Do all objects have values?
All objects have a namespace. Each item in the namespace (attribute) is
identified by (guess what) a name, and refers to a value. The value is
also an object (which is why people sometimes say "in Python everything
is an object"). You might even argue that an object is nothing *but* a
namespace with specific behaviour, though that's a somewhat extreme view.

Each object is an instance of some type, and "knows" which type it's an
instance of. (A reference to) the type is usually stored in the
instance's attribute named (for historical reasons) __class__. Once you
get really smart you'll learn that you can even the type of some objects
(the ones whose types are defined in Python rather than being built into
the interpreter) by changing the value of their __class__ attribute.

The instance's type is *also* an object, and therefore has its own
namespace. The instance (of the type) is created by calling the type,
possibly with arguments that can be used to initialise the values of
items in the instance's namespace. They can also be ignored, but there
wouldn't be much point requiring them then, would there?
2. What is the value of object()?
Well, object is a type. So calling it give you an instance of type
object. But of course you could have answered this question for yourself
in the interactive interpreter:
object() <object object at 0x0099C438>
Pay attention here:
object() <object object at 0x0099C438>

No, I didn't just copy and paste the same text. I'm using the C Python
implementation, and the first time I created an instance of type object
I didn't bind it to a name. C Python keeps a count of references to all
objects, and when the reference count falls to zero it reclaims the
space. This was promptly re-used to create the second instance.

If I bind a name to a third object (which will *also* be created at the
same address) the memory won't be reused:
a = object() # sets the ref count of the instance to 1
object() <object object at 0x0099C448> 3. If two objects are equal with "==", does that
mean their values are the same?
Almost universally, yes, although if you know enough about how the
interpreter works "under the hood" you can define the response of
instances of your own classes to the "==" operator (by defining their
__eq__ method), and even define a class whose instances aren't equal to
anything, even to themselves!
4. Are object attributes part of an object's type
or it's value, or something else? (I think the first.)
Well, this is where things become a little more complex.

Each instance of a type has some attributes defined in its own
namespace ("instance attributes"), which are therefore unique to it.
These attributes would normally be considered collectively as the
"value" of an object if you really *must* have something that you can
call the value. The attributes of an instance are accessible only by
referencing the instance and then qualifying that reference - usually
using the dot operator, but sometimes using functions like getattr().

You can, however, also use the instance to access the attributes of its
*type*, and perhaps this is what is confusing you. Because these type
attributes can be referenced via *any* instance of the type they are
considered common to all instances of a given type. Again for historical
reasons they are commonly called "class attributes".

The normal situation is that the instance attributes are used as the
instance's value, and the class attributes are used as the methods of
each instance of the type. This is why we say the type of an instance
defines its behaviour.

When you write

foo = instance.method(arg1, arg2)

you are almost always calling a function defined inside the instance
type's class definition (though this being Python there's absolutely
nothing to stop instances having callable attributes of their own too:
we are discussing "beginners' Python" here).

Under the hood the interpreter looks for an attribute called "method" in
the instance. Failing to find it, it then looks in the instance's type.

Of course it can fail to find it there, too. If the type is defined as a
specialisation of some other type (a "subclass" of the other type -
"type2 is like type1 but with the following differences") then the
interpreter will consult the other type, and so on and so on. I am
deliberately ignoring multiple inheritance ("typeC is like typeB, and
it's also like typeA") here, but the essentials are the same. We say the
subclass "inherits" the attributes of the superclass.

If the interpreter keeps walking up the inheritance tree in this way
without finding the attribute it's looking for, it will eventually
arrive at the type "object", because ultimately every object in Python
is defined as a subclass of (a subclass of (a subclass of ...)) object.

So, when you wrote above "... int(1) and int(2) have exactly the same
operations, yes? Yet their values are different" you were correct: the
operations are defined by their type ("int"), and are shared between all
instances. Unfortunately you chose an immutable type - an int object's
value cannot be changed, and so it isn't exposed to CPython's
introspection features. It's used inside the type's methods, which are
written in C and can therefore sneakily access bits of the objects that
don't live in the Python-accessible namespace.
5. The (only?) way to get an object's value is to
evaluate something (a name or a "reference"(*)
that refers to the object.
Well, most times you don't really get "an object's value", since the
value is collectively embedded within all of its attributes, and as
we've just seen, instances of immutable types don't expose their values
directly. But it's not *incorrect* to say that, just a bit fuzzy.
(*) I did not go back through this whole thread
but I know "reference" is controversial. I am not
trying to revive that debate. I mean the word in
a very generic sense.

*how* the value is represented inside the object is completely irrelevant;


...snip...
Yes, I agree and did not intend to imply otherwise.

OK, so are you ready for some fun? The dir() builtin gives you access to
the names defined in an object's namespace. Let's go hunting.
from pprint import pprint
This is just a convenience so we don't splurge across the page.
pprint(dir(object)) ['__class__',
'__delattr__',
'__doc__',
'__getattribute__',
'__hash__',
'__init__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__str__']
These are attributes that by definition every object must have (since
when told to look for them the interpreter will keep going if necessary
until it finds them in object). We can find some information out about
them by constructing a string referring to them and evaluating that
string (it's easier than typing them by hand into the interactive
interpreter).
for name in dir(object): .... print name, ":", eval("object. %s" % name)
....
__class__ : <type 'type'>
__delattr__ : <slot wrapper '__delattr__' of 'object' objects>
__doc__ : The most base type
__getattribute__ : <slot wrapper '__getattribute__' of 'object' objects>
__hash__ : <slot wrapper '__hash__' of 'object' objects>
__init__ : <slot wrapper '__init__' of 'object' objects>
__new__ : <built-in method __new__ of type object at 0x1E1AE868>
__reduce__ : <method '__reduce__' of 'object' objects>
__reduce_ex__ : <method '__reduce_ex__' of 'object' objects>
__repr__ : <slot wrapper '__repr__' of 'object' objects>
__setattr__ : <slot wrapper '__setattr__' of 'object' objects>
__str__ : <slot wrapper '__str__' of 'object' objects>
This tells us that object's type is "type" (or as we'd say colloquially
"object is a type", just as we'd say "dict is a type"). Most of the
other attributes are methods or "slot wrappers". You can regard them as
the same for our purposes, as the difference is essentially
implementation detail. Now let's look at an *instance* of type object.
b = object()
for name in dir(b): .... print name, ":", eval("b. %s" % name)
....
__class__ : <type 'object'>
__delattr__ : <method-wrapper object at 0x00AC3CF0>
__doc__ : The most base type
__getattribute__ : <method-wrapper object at 0x00AC3E90>
__hash__ : <method-wrapper object at 0x00AC3CF0>
__init__ : <method-wrapper object at 0x00AC3D10>
__new__ : <built-in method __new__ of type object at 0x1E1AE868>
__reduce__ : <built-in method __reduce__ of object object at 0x0099C438>
__reduce_ex__ : <built-in method __reduce_ex__ of object object at
0x0099C438>
__repr__ : <method-wrapper object at 0x00AC3E90>
__setattr__ : <method-wrapper object at 0x00AC3D10>
__str__ : <method-wrapper object at 0x00AC3CF0>
Here you can see that the instance is actually *wrapping* it's type's
methods. Again this is an implementation detail: the point of the
wrapper is to make the C-implemented method look like a function defined
in Python, I believe - I wouldn't claim exact certainty on that.

You can see that the __new__ method is actually directly inherited from
the type (it has the same memory address), but all the other methods and
slot wrappers of the type appear to have been wrapped.

This isn't coincidental: __new__ is the only method that doesn't *need*
to be wrapped, because it's called to *create* the instance, and so it
gets passed a reference to the *type*, not the instance.

Now let's define our own type. Because "classic classes" continue to
exist, it's still necessary at present to explicitly state we want a
type. The simplest way to do this is to subclass object (because
otherwise we'd have to discuss metatypes, and your would end up
swallowing your brain). I'm just going to define one method for this type.
class foo(object): .... "Pretty simple object subclass"
.... def foo(self):
.... print "foo.bar:", self
.... for name in dir(foo): .... print name, ":", eval("foo.%s" % name)
....
__class__ : <type 'type'>
__delattr__ : <slot wrapper '__delattr__' of 'object' objects>
__dict__ : {'__dict__': <attribute '__dict__' of 'foo' objects>,
'__module__': '
__main__', 'foo': <function foo at 0x00B2FCF0>, '__weakref__':
<attribute '__weakref__' of 'foo' objects>, '__doc__': 'Pretty simple
object subclass'}
__doc__ : Pretty simple object subclass
__getattribute__ : <slot wrapper '__getattribute__' of 'object' objects>
__hash__ : <slot wrapper '__hash__' of 'object' objects>
__init__ : <slot wrapper '__init__' of 'object' objects>
__module__ : __main__
__new__ : <built-in method __new__ of type object at 0x1E1AE868>
__reduce__ : <method '__reduce__' of 'object' objects>
__reduce_ex__ : <method '__reduce_ex__' of 'object' objects>
__repr__ : <slot wrapper '__repr__' of 'object' objects>
__setattr__ : <slot wrapper '__setattr__' of 'object' objects>
__str__ : <slot wrapper '__str__' of 'object' objects>
__weakref__ : <attribute '__weakref__' of 'foo' objects>
foo : <unbound method foo.foo>
You can see what foos inherit from the "object" superclass: almost
everything; but the foo type also has a few of its own attributes:
__dict__, __weakref__, __module__, __doc__ and bar.

__dict__ is a dictionary with several keys in it: __dict__ ,
__weakref__, __module__, __doc__ and bar. Oh, those are the class
attributes that aren't inherited from the superclass!

Right, let's create a foo instance and see what that looks like.
f = foo()
for name in dir(f): .... print name, ":", eval("f.%s" % name)
....
__class__ : <class '__main__.foo'>
__delattr__ : <method-wrapper object at 0x00B36A10>
__dict__ : {}
__doc__ : Pretty simple object subclass
__getattribute__ : <method-wrapper object at 0x00B36A10>
__hash__ : <method-wrapper object at 0x00B369B0>
__init__ : <method-wrapper object at 0x00B36950>
__module__ : __main__
__new__ : <built-in method __new__ of type object at 0x1E1AE868>
__reduce__ : <built-in method __reduce__ of foo object at 0x00B36A30>
__reduce_ex__ : <built-in method __reduce_ex__ of foo object at 0x00B36A30>
__repr__ : <method-wrapper object at 0x00B36A50>
__setattr__ : <method-wrapper object at 0x00B36A10>
__str__ : <method-wrapper object at 0x00B369B0>
__weakref__ : None
foo : <bound method foo.foo of <__main__.foo object at 0x00B36A30>>
Again you can see that the instance wraps the methods of its type (even
the ones its type inherits from type "object"). The instance also has
its own (empty) __dict__ dictionary, and a "bound method". The binding
is actually created dynamically every time the method is referenced, and
the point is to attach a reference to the instance to a reference to the
method. This instance reference is passed as the value of the first
argument (usually called "self") when the method is called.

Now let's set an attribute of f and see what changes.
f.attribute = "three"
for name in dir(f): .... print name, ":", eval("f.%s" % name)
....
__class__ : <class '__main__.foo'>
__delattr__ : <method-wrapper object at 0x00B36950>
__dict__ : {'attribute': 'three'}
__doc__ : Pretty simple object subclass
__getattribute__ : <method-wrapper object at 0x00B36950>
__hash__ : <method-wrapper object at 0x00B36A10>
__init__ : <method-wrapper object at 0x00B369B0>
__module__ : __main__
__new__ : <built-in method __new__ of type object at 0x1E1AE868>
__reduce__ : <built-in method __reduce__ of foo object at 0x00B36A30>
__reduce_ex__ : <built-in method __reduce_ex__ of foo object at 0x00B36A30>
__repr__ : <method-wrapper object at 0x00B36930>
__setattr__ : <method-wrapper object at 0x00B36950>
__str__ : <method-wrapper object at 0x00B36A10>
__weakref__ : None
attribute : three
foo : <bound method foo.foo of <__main__.foo object at 0x00B36A30>>


Well, we can see that the new attribute is included in the result of the
dir() function. But if you look carefully you'll also see that *it's
been added to the instance's __dict__ dictionary*.

Read this over a few times and you should have a pretty good idea of
what goes where. Now get on with writing that function!

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Jan 13 '06 #87
On Fri, 13 Jan 2006 03:12:00 +0000, Steve Holden <st***@holdenweb.com> wrote:
[...]
Note to nitpickers
------------------
Please note that I *am* oversimplifying here, and the nitpickers will
undoubtedly find many threadsworth of valuable material here. The point
is to develop an understanding of the *principles*. Once someone has
that they can pick up the details as they need them, which 98% of Python
users don't feel the need to. I don't even claim to know the whole
story, but I *do* know enough to explain it in principle. So by all
means correct me where I am demonstrably wring, but *please* don't just ^^^^^-- spelling is "wring" ;-)add complexity that doesn't aid understanding. [...]When you write

foo = instance.method(arg1, arg2)

you are almost always calling a function defined inside the instance
type's class definition (though this being Python there's absolutely
nothing to stop instances having callable attributes of their own too:
we are discussing "beginners' Python" here).

Under the hood the interpreter looks for an attribute called "method" in
the instance. Failing to find it, it then looks in the instance's type. UIAM, for new-style classes this is wrongly putting the instance attribute
lookup before the mro logic. For new-style, the interpreter goes down the
type(instance).mro() chain looking for the attribute called "method"
until it finds a "method" attribute whose value has __get__ method AND a __set__ method
(which makes it a data descriptor, and not overridable by an instance attribute). If
found, it will call the method.__get__ method with the instance as an argument. The __get__ method
then returns (normally) the bound method. If it finds "method" without __get__ and __set__ methods,
it will ignore it, except that it may revisit it if after the whole mro chain fails, and there isn't
any "method" attribute on the instance either. In that case, it will look for "method" again along the
mro, and if it has a __get__ method, it will form a bound method (this is the typical "method" attribute
in the form of a function, which has a __get__ method), or if there is no __get__ method, it will
return the value as ordinary class variable. The re-scan of mro is not literal, hopefully. I'm just
trying to express the logic. Also special shortcuts apply for methods of builtins, I believe.

Old-style classes live alongside new ones -- I suspect -- by virtue of type(someinstance) being
<type 'instance'> and type(someinstance).__getattribute__ thus implementing old-style stuff instead
of the type(someinstance).__getattribute__ of new-style instances, which inherit their __getattribute__
either from object.__getattribute__ or type.__getattribute__, or a user definition.

Of course it can fail to find it there, too. If the type is defined as a
specialisation of some other type (a "subclass" of the other type -
"type2 is like type1 but with the following differences") then the
interpreter will consult the other type, and so on and so on. I am
deliberately ignoring multiple inheritance ("typeC is like typeB, and
it's also like typeA") here, but the essentials are the same. We say the
subclass "inherits" the attributes of the superclass.

If the interpreter keeps walking up the inheritance tree in this way
without finding the attribute it's looking for, it will eventually
arrive at the type "object", because ultimately every object in Python
is defined as a subclass of (a subclass of (a subclass of ...)) object.

Unless the attribute access started on a type, in which case it will check
for type.method before object.method, UIAM. BTW, in order to find either
kind of attribute, there will first be a search for type(instance).__getattribute__,
which is found as object.__getattribute__ or type.__getattribute__ unless overridden
(or instance is of an old-style class as mentioned above).
I suspect these then implement the check for __getattr__, which can be user defined
to intercept attribute access on particular objects in the search chain, after
higher-priority stuff fails.

[... Can't ... keep .. eyes ... open ... for ... rest ...]
(not the fault of your prose, had a beer ;-)

Regards,
Bengt Richter
Jan 13 '06 #88
ru***@yahoo.com wrote:
The reason is that I am still trying to figure out
what a value is myself. Do all objects have values?
Yes.
If
not which do and which don't? What's the value of int(1)?
An object? Some otherwise unreachable thing that
represents the abstract concept of the number 1?
The value is the integer one. Python's 'int' is an abstract
data type. It's values are the integers.
What the value of object()? A few weeks ago I turned
to that page for enlightenment, with the results I reported.


I think type 'object' has only one value, so that's it.
--
--Bryan
Jan 13 '06 #89
Bryan Olson <fa*********@nowhere.org> writes:
ru***@yahoo.com wrote:
The reason is that I am still trying to figure out
what a value is myself. Do all objects have values?

Yes.


Can you justify this, other than by quoting the manual whose problems
caused this question to be raised in the first place?

What the value of object()? A few weeks ago I turned
to that page for enlightenment, with the results I reported.

I think type 'object' has only one value, so that's it.


In that case, they should all be equal, right?
object() == object()

False

Looks like they have different values to me.

Or maybe an object is valueless, in spite of what the manual says.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Jan 13 '06 #90
Mike Meyer wrote:
Bryan Olson writes:
ru***@yahoo.com wrote:
The reason is that I am still trying to figure out
what a value is myself. Do all objects have values?
Yes.

Can you justify this, other than by quoting the manual whose problems
caused this question to be raised in the first place?


The Python manual's claim there is solidly grounded. The logic
of 'types' is reasonably well-defined in the discipline. Each
instance of a type takes exactly one element from the type's
set of values (at least at a particular time).

What the value of object()? A few weeks ago I turned
to that page for enlightenment, with the results I reported.


I think type 'object' has only one value, so that's it.


In that case, they should all be equal, right?
object() == object()


False

Looks like they have different values to me.


Whether the '==' operation conforms to your idea of what equality
means is unclear. Maybe I was wrong, and the object's identity
is part of its abstract state.
Or maybe an object is valueless, in spite of what the manual says.


We know that's not true.
--
--Bryan

Jan 13 '06 #91
Mike Meyer enlightened us with:
I think type 'object' has only one value, so that's it.


In that case, they should all be equal, right?
object() == object() False


You compare instances of the type 'object'. They both have one value:
object() <object object at 0xb7ddb438> object()

<object object at 0xb7ddb440>

So the claim "type 'object' has only one value" is true. It's just not
the same value for all instances.

Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Jan 13 '06 #92
Sybren Stuvel wrote:
Mike Meyer enlightened us with:
I think type 'object' has only one value, so that's it.


In that case, they should all be equal, right?
> object() == object()

False


You compare instances of the type 'object'. They both have one value:
object() <object object at 0xb7ddb438> object()

<object object at 0xb7ddb440>

So the claim "type 'object' has only one value" is true. It's just not
the same value for all instances.


You're comparing identities, not values. The value is the set of things that
you can access via an object's methods (via the type). The identity is not,
in itself, a part of the value.

Python doesn't query the object to determine it's type or identity, but it
always has to query the object to access the value.

A look at the C implementation of a typical object might help:

typedef struct {
int ob_refcnt;
struct _typeobject *ob_type; /* type */
... an unknown amount of stuff used to represent the value ...
} MyObject;

In CPython, the MyObject* pointer is the identity. The ob_refcnt field is a
CPython implementation detail. The ob_type field contains the type. The
rest of the structure is known only by the MyObject type implementation.

</F>

Jan 13 '06 #93
In article <11*********************@f14g2000cwb.googlegroups. com>,
ru***@yahoo.com wrote:
....
I think the difference in our perspectives is that you already
*know* what a value is, not necessarily in a way that allows
you to write a defintion, but certainly in a way that allows
to work effectively with them.

As a Python beginner, I do not know, and I need something
more than "it is something an object has". I do NOT need
eiher some formal specifcation, nor a metaphysical discussion
that relates it to platonic ideals and other such concepts.

Surely there is some middle ground?
Well, see what you make of Steve Holden and Bengt Richter's
answers, and let us know if 1) it answers your question and
2) you can distill your new insight into a dozen words or so
for the language reference.

I'm still inclined to dispute the premise. Your example
where you demonstrate the problem:
I wanted to write a function that would dump the contents
of any object (value and attributes), and got rather confused
about values, types, repr's, etc.


In the light of the answers you're getting, you may be thinking
that this isn't a simple problem. It isn't, in principle, it's
a huge bucket of worms. But if you have a practical focus that
comes out of your actual application for this function, it could
be pretty trivial. Your choice, and likewise for the notion of
value in general.

Donn Cave, do**@u.washington.edu
Jan 13 '06 #94
Sybren Stuvel wrote:
Mike Meyer enlightened us with:
I think type 'object' has only one value, so that's it.


In that case, they should all be equal, right?

>object() == object()


False

You compare instances of the type 'object'. They both have one value:

object()
<object object at 0xb7ddb438>
object()


<object object at 0xb7ddb440>

So the claim "type 'object' has only one value" is true. It's just not
the same value for all instances.


No, that's not the issue. A type has a set of values (and a set of
operations); each instance takes one value from the type's set. I
think (I'm not sure) that object's set of values has only one element.

In Python, types are extensible, so by 'instance', I mean a direct
instance, not an instance of a class that inherits from 'object'.
Would it make sense to have a type with an empty set of values?
Sure. Such a type could never have a direct instance. Perhaps
'object' should be an abstract base class.
--
--Bryan
Jan 13 '06 #95
On Thu, 12 Jan 2006 16:11:53 -0800, rurpy wrote:
It would help if you or someone would answer these
five questions (with something more than "yes" or "no" :-)

1. Do all objects have values?
All objects ARE values. Some values themselves are complex objects
which in turn contain other values, e.g. if I execute:

L = [None, 1, "hello"]

I have created a name 'L' which is bound to ("has the value of") a list
with three items. The first item has the value of ("is the object") None,
the second has the value of ("is the object") 1, and the third is the
string "hello".

2. What is the value of object()?
These seems complicated because we are using the same word ("object") for
both the generic programming term, the class (strictly type, although the
difference is not important), and the instance itself.

Let's make it less confusing by using a case where the three things are
different:

class Foo:
pass

Foo is a class. Classes are (generic programming term) objects.
Foo() returns an instance of the Foo class. Instances are (generic
programming term) objects.

The value of Foo() is the instance. Why? int(data) returns an instance of
int, and str(data) returns an instance of str. It makes sense to say that
the value of the int instance 1 is one, the value of str instance "abc" is
the string "abc", and so forth. So we'd like to talk the same way about
more complex objects: the value of an instance is itself.

Hence the value of Foo() is the Foo instance at some particular memory
location. In this specific case, Foo() creates an object with very little
behaviour and and no distinguishing characteristics except their location
in memory, where as ints like 1 2 and 7 are easily distinguished.

Now let's return to (non-generic) object(). object is (as well as the
generic programming term) a class (strictly type, but the difference is
unimportant). object() returns an instance of class object:
object() <object object at 0xf705e3b8>

So the value of object() is some particular instance (of type object).
3. If two objects are equal with "==", does that
mean their values are the same?
Intuitively yes, but not necessarily:
3.0 == 3

True

(We want the float 3.0 to be equal to the int 3, but we can distinguish
between them by something more than their location in memory.)

You can define a custom class:

class EqualAll:
def __eq__(self, other):
return True

but that's a pathological case.
4. Are object attributes part of an object's type
or it's value, or something else? (I think the first.)
The type/class defines what attributes (generic) objects have. The value
of the attribute lives with the instance itself (that's why fred.attribute
and barney.attribute can be different). Whether you want to say the
attribute itself is part of the class or part of the instance value is, in
my opinion, not a useful question. The answer depends on which way you
want to look at it.
5. The (only?) way to get an object's value is to
evaluate something (a name or a "reference"(*)
that refers to the object.


I can't think of any other way to get at an object except by accessing
that object, or even what it would mean if there was such a way.
--
Steven.

Jan 14 '06 #96
Quoth Steven D'Aprano <st***@REMOVETHIScyber.com.au>:
| On Thu, 12 Jan 2006 16:11:53 -0800, rurpy wrote:
|> It would help if you or someone would answer these
|> five questions (with something more than "yes" or "no" :-)
|>
|> 1. Do all objects have values?
....
|> 2. What is the value of object()?

[ I assume you mean, the object returned by object(). ]

It doesn't really have a value. I can't think of any kind of
computation that could use this object directly.

|> 3. If two objects are equal with "==", does that
|> mean their values are the same?

Yes.

| >>> 3.0 == 3
| True

Evidently the value of 3.0 is the same as the value of 3.

|> 4. Are object attributes part of an object's type
|> or it's value, or something else? (I think the first.)
|
| The type/class defines what attributes (generic) objects have. The value
| of the attribute lives with the instance itself (that's why fred.attribute
| and barney.attribute can be different).

I think to be strictly accurate, attributes and their values may reside
in a class instance, or in (one of) its class(es.) In the most common
case, functions will be in the class and data will be in the instance,
but every variation on this is reasonably common.

| ... Whether you want to say the
| attribute itself is part of the class or part of the instance value is, in
| my opinion, not a useful question. The answer depends on which way you
| want to look at it.

For a given class and instance, it can be more obvious. Take the object
returned by object(), which has attributes like '__reduce__' - all those
attributes may reasonably be considered "type" and not "value".

On the other hand, there are no constraints on how you may use these
namespaces. You can use an instance, or a class, like you would use
a dictionary object, and then it's all value.

Donn Cave, do**@drizzle.com
Jan 14 '06 #97
On Sat, 14 Jan 2006 04:22:53 +0000, Donn Cave wrote:
Quoth Steven D'Aprano <st***@REMOVETHIScyber.com.au>:
| On Thu, 12 Jan 2006 16:11:53 -0800, rurpy wrote:
|> It would help if you or someone would answer these
|> five questions (with something more than "yes" or "no" :-)
|>
|> 1. Do all objects have values?
...
|> 2. What is the value of object()?

[ I assume you mean, the object returned by object(). ]

It doesn't really have a value. I can't think of any kind of
computation that could use this object directly.
Here is one:

obj_inst = object()

def computation(data):
global obj_inst
if data is obj_inst:
print FirstOneThousandPrimes()
else:
print TextOfWarAndPeace()
It isn't a particularly useful computation, but it is a computation.
|> 3. If two objects are equal with "==", does that
|> mean their values are the same?

Yes.

| >>> 3.0 == 3
| True

Evidently the value of 3.0 is the same as the value of 3.
Okay.
"3" == 3

False

Evidently the value of three is not the same as the value of three.

Let's try not to be too deep here, okay? Before asking "what is the value
of foo?", we have to agree on what we mean by "value". It is easy to tie
yourself into knots here.

|> 4. Are object attributes part of an object's type
|> or it's value, or something else? (I think the first.)
|
| The type/class defines what attributes (generic) objects have. The value
| of the attribute lives with the instance itself (that's why fred.attribute
| and barney.attribute can be different).

I think to be strictly accurate, attributes and their values may reside
in a class instance, or in (one of) its class(es.)
When you call instance.attribute, attribute may be either a class
attribute or an instance attribute. If it is a class attribute, it belongs
to the class, not the instance, even if you access it through the
attribute.

In the most common
case, functions will be in the class and data will be in the instance,
but every variation on this is reasonably common.

| ... Whether you want to say the
| attribute itself is part of the class or part of the instance value is, in
| my opinion, not a useful question. The answer depends on which way you
| want to look at it.

For a given class and instance, it can be more obvious. Take the object
returned by object(), which has attributes like '__reduce__' - all those
attributes may reasonably be considered "type" and not "value".


I don't see that "value" or "type" are opposite, I see that they are
orthogonal. The type of 1 is int, the value of 1 is integer one. The
type of object() is object, the value is itself. The type of
object().__reduce__ is method, and the value of object().__reduce__ is
the particular (generic) object bound to the name __reduce__ in the class
object namespace. That method is a class attribute, and so it part of the
value of object().
Am I the only one that wishes that object() had been given another name,
so it would be easier to talk about the generic programming concept object
and the specific Python new-style class object without confusion?
--
Steven.

Jan 14 '06 #98
Fredrik Lundh wrote:
You're comparing identities, not values. The value is the set of things that
you can access via an object's methods (via the type).
Which does make '==' kind of weird. It may or may not refer to
a method of the object.
The identity is not,
in itself, a part of the value.

Python doesn't query the object to determine it's type or identity, but it
always has to query the object to access the value.

A look at the C implementation of a typical object might help:

typedef struct {
int ob_refcnt;
struct _typeobject *ob_type; /* type */
... an unknown amount of stuff used to represent the value ...
} MyObject;

In CPython, the MyObject* pointer is the identity. The ob_refcnt field is a
CPython implementation detail. The ob_type field contains the type.


So, was it an editing error when you said that Python does not
query the object to determine its type? The type is there in the
object, and and in Python, variables and references are not typed.
--
--Bryan
Jan 14 '06 #99
Bryan Olson wrote:
The identity is not, in itself, a part of the value.

Python doesn't query the object to determine it's type or identity, but it
always has to query the object to access the value.
>
A look at the C implementation of a typical object might help:

typedef struct {
int ob_refcnt;
struct _typeobject *ob_type; /* type */
... an unknown amount of stuff used to represent the value ...
} MyObject;

In CPython, the MyObject* pointer is the identity. The ob_refcnt field is a
CPython implementation detail. The ob_type field contains the type.


So, was it an editing error when you said that Python does not
query the object to determine its type? The type is there in the
object, and and in Python, variables and references are not typed.


do you want to understand this, or do you just want to argue ?

(hint: what might the word "query" mean in this context? can you think
of a meaning that's compatible with what I wrote? would concepts like
"object", "value", "type", and "identity" be radically different on a python
implementation that used e.g. "true" garbage collection and tagged pointers
instead of CPython's approach? if so, why?)

</F>

Jan 14 '06 #100

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.