Python's scope rules

Alex Martelli aleaxit at yahoo.com
Wed Dec 20 07:28:14 EST 2000


"Brian Elmegaard" <be at et.dtu.dk> wrote in message
news:3A40813B.C04D21C at et.dtu.dk...
    [snip]
> On usenet I have now learned from skilled scientists, that Python has some
> deficiencies regarding scope rules, and I am not capable of telling them
why it
> has not (or that it has).

Some people strongly dislike Python's very simple scope rules.  I
happen to like them, although they may get richer (and, alas, less
simple) pretty soon.


> In Aaron Watters 'The wwww of python' I have read that Python uses lexical
> scoping with a convenient modularity. But, other people tell me it does
not.
> Some say it uses dynamic scoping, some say it uses it own special
> 'local-global-builtin' scope. What is right?

The only totally-wrong idea here is that Python uses dynamic scoping:
it doesn't!  It's lexical, but *not nested*; which equates to the
local-global-builtin idea.


> The above mainly is a theoretical question. A more practical example which
I
> agree seems a bit odd is:
>
> Python 1.5.2 (#1, Mar  9 2000, 17:40:34)  [GCC 2.95.2 19991024 (release)]
on hp-
> uxB
> Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> >>> x=24
> >>> def foo():
> ...     y=2
> ...     print x+y
> ...
> >>> def bar():
> ...     x=11
> ...     foo()
> ...
> >>> bar()
> 26
> >>>

bar's "x=11" defines its x as a local variable.  Remember
Python does not have 'declarations': the 'assignment
statement' is what defines the variable's existence.

foo doesn't _define_ x, just _uses_ it, and thus, since
there is no x in local scope, the global scope is then
searched, and an x (bound to 24) is found there.

If bar wants to affect ('re-bind') the _global_ variable
x, rather than defining its own local x, it must be
explicit about it:
    def bar():
        global x
        x = 11
        foo()

However, relying on the modification of global variables
is more often a bad idea rather than a good one; if you
avoid it wherever you can do so without excessive hardship,
you'll be quite happy about the several maintenance issues
you'll eschew (and this is not a specifically Python issue;
mutable global variables can be troublesome in any language
that supports them).


> Well, I can live with it. In Fortran I would always put all the variables
to be
> passed in the parameter list. Other people say that Fortran is not easy,
and
> this example shows how stupid python is. It does?

In Fortran, you were QUITE wise to use parameter lists for
their intended purpose, rather than (ab)using the COMMON
(or named-common) area(s).  Having had to maintain not a
little Fortran in my time, I wish all Fortranists were as
wise as you:-).  Follow similar strategies in Python, and
you'll have similar advantages.

Python offers you another easy possibility, which is to
bind values to *instance attributes* -- and THAT is often
easiest and most powerful.

If anybody thinks that Python's requirement of an _explicit_
'global' statement, when global variables must be modified,
is 'stupid', then I suspect they have not thought deeply
enough about the issues, or else lack real-world experience
to have taught them why global variables NEED to be handled
with care and restraint.

This has relatively little to do with Python scoping rules,
by the way; those enter the issue when you have a function
nested inside another function, etc.  The fact that global
variables are accessed implicitly in functions that only
'read' them, but need an explicit 'global' statement in
functions that want to *re-bind* them, is a separate issue,
and, I dearly hope, one that will be maintained if and
when nested scopes are introduced: _accidental_ rebinding
of variables in outer scopes would otherwise be a danger!


> Hopefully not, but probably, this is a faq, but I have not been able to
find
> anything on the matter.

http://www.python.org/doc/FAQ.html, question 4.36, is
probably the most-relevant one -- because this is not
really a scope issue.  The 'local scopes do not next'
issue is addressed in question 4.5.


Alex






More information about the Python-list mailing list