Label-Value (was: Re: Inheriting the @ sign from Ruby)

Fredrik Lundh fredrik at effbot.org
Tue Dec 12 12:37:58 EST 2000


Roy Katz wrote:
> > The real problem is that many Python tutorials fail to explain
> > how things work (or hide it somewhere in the exercises), but
> > that's not really Guido's fault...
>
> Tough for the new Python programmer, then.  It's nt fair to them.

Sorry, but I don't understand that comment.  I've done a lot
of Python training lately, and nobody has had any problems
whatsoever understanding this.

(well, Lisp and Smalltalk programmers seem to have trouble
understanding why anyone would do things in any other way...)

> > (Hint: Everything is a reference to an object.  Variables are
> > named references, not actual objects.  Some objects can be
> > modified in place.  Some cannot be modified.  That's all)
>
> Okay! tell me, which are the objects which cannot be modified in place? I
> assume these are int's, long's, float's, etc.  Strings, lists, objects and
> dictionaries are call-by-reference.  Pardon my choice of diction, but I am
> against inventing new terminiologies (modified-in-place??).

Sigh.  The problem is that you keep using terms that mean
something for you, whether or not they apply to the current
situation.

If you want to learn something new, you have to stop doing
that.

Reset your brain.

Python doesn't use call-by-value, and it doesn't use call-by-
reference either (at least not given your definitions of those
terms).

Realize that there are more than one way to do it.

Here's how it's done in Python:

:::

All Python objects has the following:

    -- some content
    -- an unique identity (a integer, returned by id(x))
    -- a type (returned by type(x))

You cannot change the identity.

You cannot change the type.

Some objects allow you to change the *content* (without
changing the identity or the type, that is).

Some objects don't allow you to change the content
(more below).

The type is represented by a type object, which knows
more about objects of this type (how many bytes of
memory they usually occupy, what methods they have,
etc).

:::

Objects may also have:

    -- zero or more methods (provided by the type object)
    -- zero or more names

Some objects have methods that allow you to change the
contents of the object (modify it in place, that is).

Some objects only have methods that allow you to access
the contents, not change it.

Some objects don't have any methods at all.

Even if they have methods, you can never change the type,
nor the identity.

Things like attribute assignment and item references are just
syntactic sugar (more below).

:::

The names are a bit different -- they're not really properties
of the object, and the object itself doesn't know what it's
called.

An object can have any number of names, or no name at all.

Names live in namespaces (such as a module namespace, an
instance namespace, a function's local namespace).

Namespaces are collections of (name, object reference) pairs.
(Or in other words, they're dictionaries).

When you call a function or a method, it's namespace is
initialized with the arguments you call it with (the names
are taken from the function's argument list, the objects
are those you pass in).

:::

Assignment modify namespaces, not objects.

In other words,

    name = 10

means that you're adding (or replacing) the name "name" in
your local namespace, and making it refer to an integer object
containing the value 10.

    name = 10
    name = 20

means that you're first adding the name "name" to the local
namespace, and making it refer to an integer object containing
the value 10.  You're then replacing the name, making it point
to an integer object containing the value 20.  The original "10"
object isn't affected by this operation, and it doesn't care.

In contrast, if you do:

    name = []
    name.append(1)

you're first adding the name "name" to the local namespace,
making it refer to an empty list object.  You're then calling a
method on that object, telling it to add an integer object to
itself.

Things like "name.attr" and "name[index]" are just syntactic
sugar.  The first corresponds to __setattr__/__getattr__, the
second to __setitem__/__getitem__, depending on which side
of the assignment operator they appear).

That's all.

:::

> I want to know where this is documented.  Specifically, where is the
> dichotomy of ints/longs/floats vs. objects/strings/lists/dictionaries.

There is no dichotomy.  Some objects have methods that let
you modify them, some don't.  Read the language reference.
If you stop thinking in C terms, you may understand what it's
talking about.

> While I'm brainstorming with Python grammar changes, what about a real &
> operator.  No more of this hokey is-it-modifiable-in-place-or-not
> business.  Explicit control is important.

As I just explained, Python doesn't work that way.

</F>







More information about the Python-list mailing list