Are circular dependencies possible in Python?

Michael Spencer mahs at telcopartners.com
Sat Apr 9 12:36:46 EDT 2005


Tim Tyler wrote:
> Like C, Python seems to insist I declare functions before calling
> them - rather than, say, scanning to the end of the current script
> when it can't immediately find what function I'm referring to.
> 
> C lets you predeclare functions to allow for the existence of
> functions with circular dependencies.
> 
> Does Python allow you to do something similar?
> 
> If not how do you create functions with circular dependencies in
> Python - where function A could call function B; and function
> B could call function A - or is that not possible?
Of course, for example:

def A(*args):
     if len(args) > 1:
         print "Calling B%s" % repr(args[1:])
         return B(*args[1:])
     else:
         print "A Called with: %s" % args[0]

def B(*args):
     if len(args) > 1:
         print "Calling A%s" % repr(args[1:])
         return A(*args[1:])
     else:
         print "B Called with: %s" % args[0]

  >>> A("Arg1","Arg2","Arg3","Arg4")
  Calling B('Arg2', 'Arg3', 'Arg4')
  Calling A('Arg3', 'Arg4')
  Calling B('Arg4',)
  B Called with: Arg4
  >>>

Functions have to exist before you call them, but they are not 'declared'.  def 
and its enclosed suite is a statement, like print, while, etc...  The def 
statement is executed to define the function.  For functions defined at module 
level, this statement is executed when the module is first imported (or 
reloaded) in source-code order along with any other module-level code.

Executing a def statement compiles (but does not execute) the body of the 
function.  Each function, when def'd also gets a reference to the global scope 
in which it is defined.  When you execute the function body (by calling the 
function), identifiers that are not resolved in the functions own local scope 
are looked up in this global scope.

So in the example above, the body of A calls B.  B is not defined in A's local 
scope, so it is looked up in A's globals, which is the module.  As long as def 
B(... has been executed in the same module before you first call A, everything 
is fine.


Michael




More information about the Python-list mailing list