FAQ 1.7.3 : How can I have modules that mutually import each other

John Machin sjmachin at lexicon.net
Sat Mar 19 23:25:30 CET 2005

On 19 Mar 2005 12:05:18 -0800, "MackS" <mackstevenson at hotmail.com>

>I'm new to Python, I've read the FAQ but still can't get the following
>simple example working:
># file main_mod.py:
>global_string = 'abc'
>def main():
>    import auxiliary_mod
>    instance = auxiliary_mod.ClassA()
>    instance.fun()
># file auxiliary_mod.py:
>class ClassA:
>  def fun(self):
>    import main_mod
>    print 'this is ClassA.fun() and global_string is ' +
>In words, the problem is: I've a main module which defines a global
>variable and instantiates a class defined in a second module, and a
>method of that class needs to access the global variable defined in the
>main module.

Needs??? Sorry to be blunt, but this is an intrinsically ludicrous
concept, in *any* language. The whole idea of modules is (wait for it)
"modularity". "A imports B which imports A" is an utter nonsense.

>When I run main_mod.py the method is executed twice:

Care needs to be taken in general with a module that is to be RUN as a
script as well as imported; for further details, and an explanation of
why your method is executed twice, see sample code at the end of my
post. Please note: I'm showing you this because it's something you
need to know about Python quite *independently* of the fubaristic
circular import thing.

>How can I avoid this problem even in this simple example?

Don't have circular imports.

>How can I get this simple example to work?

You shouldn't try. Refactor. NOTE: "executed once only" doesn't mean
that it is "working".

=== mainmod.py ===
global_string = 'abc' 

def main(): 
    import auxmod 
    instance = auxmod.ClassA() 
    # don't need this: return 

print "Statements are also EXECUTED when the module is imported."
print "Best to avoid statements with side-effects."
print "Got the picture now?"

if __name__ == "__main__":
    print "Being run as a script i.e. not imported."
    print "Done ..."

=== auxmod.py ===
trip_count = 0
class ClassA: 
    def fun(self): 
        global trip_count
        trip_count += 1
        saved_tc = trip_count
        print 'ClassA.fun -- before importing mainmod; tc =',
        import mainmod 
        print 'ClassA.fun -- after  importing mainmod; tc =',
trip_count, 'saved_tc =', saved_tc
        print 'global_string is', mainmod.global_string 

More information about the Python-list mailing list