Python's scope rules

Terry Reedy tjreedy at
Wed Dec 20 12:47:09 EST 2000

"Brian Elmegaard" <be at> wrote in message
news:3A40813B.C04D21C at
> I am not a computer scientist, just an engineer knowing how to program in
> Fortran, Pascal,... So I after reading some of the python material on the
web, I
> decided to give it a try and is now using the language some, finding it
fun and
> easy.

I'm a statistician who discovered the same thing about four years ago.

> On usenet I have now learned from skilled scientists,

By their own evaluation? Think instead 'CS theologians' or even 'religious

> that Python has some  deficiencies regarding scope rules, and I am not
> of telling them why it  has not (or that it has).

Deficiency is in the eye of the beholder.  This religious discussion has
been going on for at least since I started listening; probably has since
the beginning of Python; and will probably continue until Python dies.
Consider not getting too involved.

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

I have discovered that while good computer scientists may develop a
definsible terminology that they use consistently each unto themselves,
they do not always agree.  This seems to one of those areas where language
is not settled.

> The above mainly is a theoretical question.

A question like 'what is the optimal asymptotic efficiency of a sorting
algorithm based on comparisions' has an answer: n log n.  The scope
discussion does not seem to.

> A more practical example which I  agree seems a bit odd is:
> >>> x=24
> >>> def foo():
> ...     y=2
> ...     print x+y
> ...
> >>> def bar():
> ...     x=11
> ...     foo()
> ...
> >>> bar()
> 26

When a function encounters a name that is not in its local scope, where
should it look to find a value to substitute (given that there are no
explicit pointers)?  There are three general answers: nowhere (raise an
exception or abort); somewhere in the definition environment; or somewhere
in the usage environment.  Python's current answer is in the namespace of
the defining module (and then in the builtin namespace attached to that

The only things I find 'odd' (and definitely confusing at first) is the use
of 'global' for the module namespace (and I suppose there is some history
here) and the sometimes claim that there are two rather than three possible

For odd behaviour, consider the following possibility:
_dimension = 2
def SegSectTri2d(line_segment, triangle):
  "does line_segment intersect triangle in xy-plane"
  # uses _dimension and depends on it being 2
import plane_geometry
_dimension = 3
def SegSectTri3d(line_segment, triangle):
  "does line_segment intersect triangle in xyz-space"
  # uses _dimension and depends on it being 3
  # uses plane_geometry.SegSectTri2d() for part of its calculation

Now, I would be disappointed if the plane geometry functions did not work
when called from space geometry functions because the two modules happened
to use the same spelling for the private dimension constant.

Terry J. Reedy

More information about the Python-list mailing list