En Wed, 19 Nov 2008 01:14:28 -0200, <[EMAIL PROTECTED]> escribió:
On Nov 18, 10:22 am, Steve Holden <[EMAIL PROTECTED]> wrote
in thread "Python-URL! weekly Python news and links (Nov 17)":
[EMAIL PROTECTED] wrote:
[...]
One of the reasons I would like to formulate a good
model of an object's value and type is so that I could
try to offer something better.  Responses like yours
are significantly demotivating.

And yet you argue when people try to explain to you that objects don't
*have* values, objects *are* values. Objects have attributes, which are
references to other values. One of an object's attributes is its type.

I am sorry for arguing with you.  I hear you
and others saying that the value (in the english
language sense of value) of an object *is* the
object.

But before I address that, I am a little confused
by what you wrote above.  Quoting the PLR again,
"Every object has an identity, a type and a value."
I presumed "value" to include attributes.  Are you
saying the correct statement in the PLR should have
been, "Every object has an identity, attributes, and
a value"?

I'll try to avoid any confusion here. I cannot say what defines a Python object in a generic way, but I do know what defines a CPython object. That is, I can talk about the current C implementation. In CPython, an object is a C struct: PyObject. No more, no less. Most functions in the CPython API receive, return, or handle PyObject pointers everywhere. Every object in CPython is represented as a PyObject instance, and has the following properties:

- An object has *identity*: its memory address, immovable, fixed once the object is allocated. - An object has a *type*: its ob_type field (a pointer to the type object). The type is uniquely defined - no type inference is ever done. It may be changed after the object was created but only if several prerequisites are met.
 - An object has *state* [or value]: everything else stored in the struct.

The PyObject struct is very small and contains nothing apart from the ob_type field [1]. So a PyObject instance has no state, there is nothing more defining it. A PyObject instance just "is": it has only identity and type, it does not carry any state.

More useful objects are built by extending the PyObject struct at the end - that is, adding more and more fields. By example, a PyIntObject adds a C "long" field. That new field is the only difference between a PyIntObject and a bare PyObject. We can say that a PyIntObject gained some "state": the integer stored inside that field; some people would like to say "its value". So, to describe completely a PyIntObject, one has to tell -in addition to its type and identity- *which* number it contains.

More complex objects are built using the same principle: by example, a PyFunctionObject contains nine more fields (func_code, func_doc, etc.) in addition to the bare PyObject. Those additional fields represent the "state" of the function object, and are required to describe it completely.

Instances of user-defined classes may contain arbitrary attributes; this is implemented using a dictionary. We refer to this dictionary as the '__dict__' attribute in Python code, but it is just another field in the object struct, as anything else. In other words, arbitrary attributes are also stored (indirectly) in the object struct.

So, at least when one looks at the CPython implementation, things are rather simple: an object is a struct located at certain address (determines its identity), has a certain type (a field in the struct) and has a state (everything else in the struct).

You may want to say "value" instead of "state" in all the above description, but I think it becomes confusing later.

Expressions: Evaluating an expression yields a result, and that result is an *object*. One could say "the value of this expression" -- but remember that it is an *object*, like everything else in Python. If one says "objects have identity, type and value", one cannot say at the same time "expressions return a value" because the word "value" has a different meaning in both sentences.

Calling: Same problem applies to "call-by-value". If one says that objects *have* a value (that implies that value is *part* of the object), it itsn't its "value" what is passed when a function call is made. The *whole* object is passed, not its "value" alone. Saying "call-by-object" describes more accurately what actually happens.

Conclusion: To avoid any ambiguity, I'd say that "objects have identity, type, and state" (not value), "expressions evaluate to an object" (again, not value), and "Python passes arguments to functions using a call-by-object protocol". Given these terms, even "the value of this expression" might be acceptable because "value" could not be confused with any "part" of an object.

Here is why I am having trouble accepting the
explanations you and others have kindly offered
me.  If values are objects then the words "object"
and "value" are synonymous, yes?  Fine, I can see
that could be a desirable thing.  Value is more
natural than object for people coming to Python,
for example.

"state" is more common in OO theory, I think. I'd reserve "value" to any informal description, and use "state" when refering to "anything the object carries with itself".

I hope you see why I find the "value is object"
to be an unacceptable explanation of Python
objects.

Me too. I hope the above explanation helps to understand the difference. It is based on a specific implementation, but I feel that describing what CPython actually does is easier that talking about abstract concepts. Perhaps somebody can come with an abstract explanation based on this concrete examples.

[1] There is another field always present: ob_refcnt, but it should be considered an implementation detail of the reference counting mechanism. Additional fields may be present in a debug build of Python.

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to