import order or cross import

Duncan Booth duncan.booth at invalid.invalid
Wed Jan 3 05:56:14 EST 2007


Roland Hedberg <roland.hedberg at adm.umu.se> wrote:

> Now, running ONE.py causes no problem it will print "Black", but running
> TWO.py I get:
> AttributeError: 'module' object has no attribute 'BaseColor'
> 
> So, how can this be solved if it can be ?
> 

When you execute an import statement, it checks whether the module already 
exists. If it does exist then it immediately returns the module object. If 
the module does not yet exist then the module is loaded and the code it 
contains is executed.

Remember that all statements in Python are executed at the time they are 
encountered: there are no declarations (apart from 'global') so no looking 
ahead to see what classes or functions are coming up.

One other complication in your particular instance: when you run a ONE.py 
as a script the script is loaded in a module called '__main__', so 'import 
ONE' will actually load a separate module which is NOT the same as the 
__main__ module. Likewise when you run TWO.py as a script you have three 
modules __main__ (loaded from TWO.py), ONE, and TWO.

So running TWO.py, you get:

   import ONE
      --- loads the module ONE and starts executing it
      import TWO
          --- loads the module TWO and starts executing it
          import ONE
              --- the module ONE already exists 
                  (even though so far it hasn't got beyond
                  the import TWO line) so the empty module is returned.
      class Black(ONE.BaseColor):
              --- ONE doesn't have a BaseColor attribute yet so you get 
                  an error.

The fix in this sort of case is usually to extract the base class out to a 
third module. If you put BaseColor in base.py then you can safely import 
that anywhere you want it.

An alternative in this case would be to edit ONE.py and move the line 
'import TWO' down below the definition of BaseColor: nothing before that 
actually requires TWO to have been imported yet.

However, you really should try to separate scripts from modules otherwise 
the double use as both __main__ and a named module is going to come back 
and bite you.



More information about the Python-list mailing list