nested scopes

Jeremy Hylton jeremy at alum.mit.edu
Fri Feb 2 18:07:10 EST 2001


In article <qUQrSUAN$we6EwEu at jessikat.fsnet.co.uk>,
  Robin Becker <robin at jessikat.fsnet.co.uk> wrote:
  [reflecting on the virtues of 'from ... import *':]
> I really don't understand why this short cut should be considered such
> an abomination. Not using it leads to bad maintenance problems ie I
> either flood my module with names by importing right at the top or I
> am forced to explicitly import in the target scope. Any name changes
> in the origin module must then be pursued over the whole world.

I don't understand your complaint.  The first part I follow: You don't
want to import names into the module scope.  Then you say that explicit
imports will cause you to pursue changes over the whole world.  I don't
get that.

If you have a function that does "from mymodule import *", you
presumably use some names defined in mymodule like eggs or spam.  If you
change mymodule so that eggs is replaced with beans, you've got to track
down any client of mymodule and update it.  If you used "from mymodule
import eggs", then you could search for all import lines that mention
mymodule and eggs and find all the cases.  (This is pursuing it over the
whole world, but it's what you get when you change the interface of a
module.)

If you used "from mymodule import *", you'll need to search for all
scopes that import mymodule and then see if they also use the name
eggs.  It's much harder to find all the cases, because you aren't being
explicit about which names you're using from mymodule.

On the third hand, if you change the name foo in mymodule to bar, but
foo was not used, then it's immaterial whether you used import * or an
explicit import.

Unless I'm missing something, your maintenance problems are reduced by
never using import *.

> As for the compiler statically determining what's in scope I thought
> the whole point of python was that it was dynamic and did late
> binding.

I think that's a bit of an exageration :-).  I don't think there's a
"whole point" to Python.

> I can't figure out how any compiler is going to figure out
> that
>
> def outer(name):
>     exec name + '=1'
>     def inner():
>         return g
>     return inner()
>
> can work if I call outer('g') so this must only be static scoping; if
> it's static why should dynamic events like imports be clashing with
> it. I suppose there's some attempt at code optimisation being pursued.

Interesting point you raise.  The compiler is supposed to flag this as
an error, just like import * and for exactly the same reason.  Dynamic
name binding via exec or import * are at odds with static scoping -- and
you shouldn't try to mix the two.  I'll have to fix this in the next
release.

--
-- Jeremy Hylton, <http://www.python.org/~jeremy/>


Sent via Deja.com
http://www.deja.com/



More information about the Python-list mailing list