Mutually referencing imports -- impossible?

Carl Banks pavlovevidence at gmail.com
Sun Jul 13 20:30:36 CEST 2008


On Jul 13, 1:55 pm, Matthew Wilson <m... at tplus1.com> wrote:
> I started off with a module that defined a class Vehicle, and then
> subclasses Car and Motorcycle.
>
> In the Car class,  for some bizarre reason, I instantiated a Motorcycle.
> Please pretend that this can't be avoided for now.
>
> Meanwhile, my Motorcycle class instantiated a Car as well.
>
> Then I moved the Car and Motorcycle classes into separate files.  Each
> imported the Vehicle module.
>
> Then I discovered that my Car module failed because the global
> Motorcycle wasn't defined.  The same problem happened in my Motorcycle
> module.  Car and Motorcycle can't both import each other.
>
> In the beginning, when all three (Vehicle, Car, and Motorcycle) were
> defined in the same file, everything worked fine.
>
> I don't know how to split them out in separate files now though and I
> really wish I could because the single file is enormous.
>
> Any ideas?

First thing to do is ask yourself:
Are the Car and Motorcycle being created at import time, or are they
being created after the imports by a function call?

If it's the former, then yes, it's impossible.  You can't do this, for
instance:

car.py:
-----------------
import motorcycle
a = motorcycle.Motorcycle()
-----------------

motorcycle.py:
-----------------
import car
b = car.Car()
-----------------


However, you can stick them in functions and call them afterwards and
it will work:

car.py:
-----------------
import motorcycle
def create_motorcycle():
    global a
    a = motorcycle.Motorcycle()
-----------------

motorcycle.py:
-----------------
import car
def create_car():
    global b
    a = car.Car()
-----------------

vehicle.py
-----------------
import car
import motorcycle
car.create_motorcycle()
motorcycle.create_car()
-----------------


Second, if you're using from ... import statements, it won't work; you
should change it to use plain imports as I did above.  So the
following wouldn't work :


motorcycle.py:
-----------------
from car import *
a = Motorcycle()
-----------------

car.py:
-----------------
from motorcycle import *
b = Car()
-----------------



Third, if Motorcycle and Car are inside packages, you still need to
avoid from ... import even just to import the module (unless you're
willing to hook into the import machinery).  For example, if car.py,
motorcycle.py, and vehicle.py are all parts of the package carsim,
then you'd have to do this:

motorcycle.py:
----------------
import carsim.car
def create_car():
    global a
    a = carsim.car.Car()
----------------

and not

motorcycle.py:
----------------
from carsim import car
def create_car():
    global a
    a = car.Car()
----------------

This last limitation is due to a wart in the import logic.


Carl Banks



More information about the Python-list mailing list