nested scopes

D-Man dsh8290 at rit.edu
Mon Feb 5 12:42:42 EST 2001


On Mon, Feb 05, 2001 at 02:01:58AM -0800, Nathaniel Gray wrote:
| Tim Peters wrote:
| 
| > Whether a name is local to a given scope is, in Python, determined by
| > whether the name is *bound* somewhere in that scope.  "import *" counts as
| > a
| > binding, but the compiler has no idea which names are being bound.  So
| > when compiling code for a nested function N, referencing a non-local name
| > (one that is not bound to within N's body) X, the compiler has no idea
| > which scope X belongs to if an "import *" (or "exec" stmt) appears in an
| > enclosing
| > function E.  Any name whatsoever *may* become local in E then, but it's
| > impossible to know anything about that at compile-time.
| 
| Interesting issue.  What if the following was allowed:
| >>> from tim_bot_module import tb*
| 

Hmm, wouldn't it be better to use :

>>> import tim_bot_module as tb
>>> tb.name_you_want_to_use

?

IMO prefixing names with strings like "tb" is for namespace-less
languages like C.  Since python has namespaces, why not use them?


What I wonder about is whether names defined in a try block or a for
block will still exist outside the block.

Take this Java code for example:

String s ;
try
{
	s = some_func_that_might_throw() ;
}
catch ( ThrownException ex )
{
	s = "Some other value" ;
}


So you look at it and whether the function throws an exception or not,
s has been initialized appropriately.  javac won't compile this since
"s might not be initialized".

In Python, it is much nicer :

try :
	s = some_func_that_might_throw()
except ThrownException :
	s = "Some other value"

and everything works as expected.  If the exception was thrown, s will
have the one value, if not it will have the other.


Will the new nested scopes require me to write:

s = None # make the name exist in this scope first
try :
	...

?


I think it is acceptable if variables like loop counters and temps
inside a loop don't exist in the function's namespace. ie:

for i in range( 10 ) :
	pass
print i # this gives NameError


but :

i = 1
for i in range( 10 ) :
	pass
print i # prints '9' since the name i already existed and was rebound



What I wonder about is how important/useful nested scopes really are.
When I first learned python, I had an Eiffel/C++/C background with
maybe a little Java.  Each of those has nested lexical scopes.  I
thought python was weird and lacking.  I have since learned that
python is quite natural and doesn't require various ugly idioms
(declaring the variable at the top) to make the assignment in the
nested scope persist outside the loop/if/whatever. 

Last quarter I took a class called "Programming Language Concepts"
that discussed the design of programming languages.  It was the first
time I had heard of dynamic scoping.  (Actually, I think I saw it
mentioned in a lisp context, but I didn't know what it meant)  The
professor didn't know of any situations where it would be
advantageous, and I couldn't contrive any either.  I was kind of
surprised when I heard python described as "dynamically scoped"
because its scoping was really quite natural for me.  The [23]-level
scoping makes the dynamic scoping almost static and I don't see that
as a weakness.

I really don't know, at this moment, whether adding nested static
scopes will strengthen or weaken the language.

just-a-few-thoughts-ly y'rs -D





More information about the Python-list mailing list