Official definition of call-by-value (Re: Finding the instance reference...)
gagsl-py2 at yahoo.com.ar
Wed Nov 19 07:50:45 CET 2008
En Wed, 19 Nov 2008 01:14:28 -0200, <rurpy at yahoo.com> escribió:
> On Nov 18, 10:22 am, Steve Holden <st... at holdenweb.com> wrote
> in thread "Python-URL! weekly Python news and links (Nov 17)":
>> rurpy at yahoo.com 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
> 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 . 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
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
 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.
More information about the Python-list