Python recursive function question

Randall Hopper aa8vb at yahoo.com
Mon Aug 28 14:31:00 EDT 2000


Calvelo Daniel:
 |Randall Hopper <aa8vb at yahoo.com> wrote:
 |
 |:      First, if you define a single recursive function A defined at file
 |: scope, it can call itself as expected; but if you have a helper function B
 |: defined in A, B "cannot" call itself.  You apparently have to move it to
 |: file scope:
 |:
 |:      def InsertionSort(...):
 |:
 |:        def Insert(...):
 |:          ...
 |:          Insert(...)
 |
 |At this point, 'Insert' is not defined. The current scope is global+local;
 |Insert is not yet into local scope (it will be at the end of the declaration)
 |and it is not into global scope (the "file" scope you refer to). 

Thanks for the reply.  I still wasn't quite sure why Insert wasn't in the
local scope "inside" of Insert, until I ran a few more tests.

>From the code below, I found out that Python flushes locals() when it
enters a nested scope, rather than creating of a copy of the parent
locals() it pushed onto a stack somewhere (i.e. copy all the current locals
bindings into a new dictionary).  I'd suspected it did the latter, since it
has to save-off the parent locals anyway.  As a result, the nested function
loses track of it's own symbol definition (the function symbol binding).

Now I understand that "Python does not have arbitrarily nested scopes" in
simple terms translates to "locals() flushing" when entering nested scopes.
And "new n.s." in section 4.1 of the LangRef means "new empty n.s.", not
"new duplicate n.s."

While locals() flushing is simpler behavior, the asymmetry in the
callability of functions it introduces isn't quite intuitive.  Fortunately
nested recursive functions can be easily written other ways.

------------------------------------------------------------------------------
print "1: globals() has f =", globals().has_key('f')
def f():
  print "3: globals() has f =", globals().has_key('f')
print "2: globals() has f =", globals().has_key('f')

f()

def f2():
  print "1: locals() has g =", locals().has_key('g')
  def g():
    print "3: locals() has g =", locals().has_key('g')
    print "3: locals()       =", locals()
  print "2: locals() has g =", locals().has_key('g')
  g()

f2()
------------------------------------------------------------------------------
::OUTPUT::

1: globals() has f = 0
2: globals() has f = 1
3: globals() has f = 1        <----
1: locals() has g = 0
2: locals() has g = 1
3: locals() has g = 0         <----
3: locals()       = {}
------------------------------------------------------------------------------

-- 
Randall Hopper
aa8vb at yahoo.com




More information about the Python-list mailing list