A bundle of questions from a Python newbie

Justin Sheehy justin at iago.org
Thu Feb 21 02:18:12 EST 2002


Gonçalo Rodrigues <op73418 at mail.telepac.pt> writes:

> 1. The way I thought that an assignment like
>
> var += 1 
>
> worked was that the interpreter would go to the place pointed by var and
> add 1. In particular, id(var) should remain constant. But this is not
> what happens as a simple test shows it. So what is wrong in my
> perception of what += does? Is this an implemetation issue?

First consider what happens when you do "var = 1":

 - an integer with value 1 is created
 - the name "var" is bound to that integer

In the case you show above, "var += 1" is equivalent to "var = var + 1":

 - an integer with value 1 greater than the value that var is bound to
   is created
 - the name "var" is bound to that integer

A shorter way to say this is that Python's assignments are simply name
bindings and do not modify the values that the names may formerly have
been bound to.  

I should note, however, that the += operator does have the ability to
do what you describe, but only on mutable objects that choose to
enable that behavior.

> 2. What is the idea of having in the loop
>
> for var in range(10):
>     pass
>
> the var variable still available after it? Wasn't it supposed to die (as
> in being out of scope) when the loop ends?

A for loop does not introduce a new scope.  Thus, the variables
created in a for loop continue to exist after the loop finishes.

> And is this a feature, or something that we should not count on?

You can count on it.  Many people use this feature.

> Somehow, I believe that the a new var should be created when the
> loop starts and then destroyed when it ends avoiding any variable
> shadowing along the way.

Aesthetically, that's not a bad idea.  But that's not how it works.  :-)

> 3. This is not a question just a small complaint. I really miss the
> do-until control flow in Python. I always have to waste some extra brain
> cycles to convert it to the while 1, etc. idiom. Hey, we all have a
> right to our complaints, right? ;-)

Sure.  Complain away.  I personally dislike it when languages provide
too many redundant control-flow structures.  More to remember.

> 4. I have read the FAQ about the "self controversy"

There's not much of a controversy among actual users of Python.  I
think that "self" seems to get less flack than the indentation use,
and both are primarily picked on by people that haven't used Python
enough to understand the benefits of the simple explicitness involved.

> I really feel that there must be a better solution. I thought
> something like this could be useful:
>
> a. self doesn't need to be declared.
>
> b. Distinguishing data members from local variables could be achieved by
> instead of using self.whatever use .whatever - a single dot in front of
> the name "whatever".
>
> I don't expect that this solution is adopted (it would break all the
> existing code - ahhh every Nero-like language designer's dream - wreak
> havoc in the citadel of its users and start afresh), what I would like
> to know is how bad/good is this idea.

There is a lot of value to the current model with "self" explicit.  It
is in line with Python's general virtue of explicitness, it leads to
cleanliness in how methods work generally, and provides a simple and
obvious distinction between instance variables and other names.

How good is your idea?  It's fine, if you're designing a new language.
However, for Python, I believe that the current model is better than
yours.  Even if it could be changed at this late date, it shouldn't be.

> Still, What's the rationale behind allowing
>
> class L(list):
>     pass
>
> L.answer = 42
>
> but then not allowing 
>
> L.__dict__['answer'] = 42

What exactly are you trying to accomplish here?

Basically, subclasses of builtin objects like list don't have a normal
dict.  They have a dict-proxy that does everything it needs to.

Why do you think that you want to assign to the class's __dict__?

> 9. What would be better in terms of speed?
>
> for i in range(<whatever>):
>     <whatever> 
>
> Or to code an iterator like

The for loop will almost always be faster for simple cases.  Use
iterators for their useful behavior, not for speed.

> 10. I have a class that works like a list in the sense that supports the
> method __getitem__ and its relatives. But I'm at a loss as to what I
> have to do to support the slice notation.

You could start with __getslice__ and __setslice__.

> 12. This is not exactly about Python, but about programming in general.
> I keep reading about continuations and coroutines and I would like to
> know, in simple terms if possible, what the heck are they and in what
> ways they differ from generators as they exist in Python.

I'll try a quick explanation of continuations.

At any given time in program flow, the current continuation can be
thought of as "the rest of the program", with a hole in it for the
thing currently being executed.  For instance, in the code segment:

f(g(x))

g's continuation is effectively:

f(_)  where "_" is to be filled in when the continuation is run.

Think of your continuation as a function of one argument that will
take your return value as its argument.  It represents everything
that will happen in the program onward from the time that you return.

Unless you have explicit control over them, continuations are just
return points.  If you do have the ability to explicitly handle them,
they are primarily useful for implementing other program control flow
contructs.  

It is rare for continuations to be used directly for something other
than implementation of a control-flow construct.  So, unless you plan
on creating (e.g.) a new microthread system, this simple explanation of
continuations is probably all you'll ever need to know.

-Justin

 





More information about the Python-list mailing list