10

Possible Duplicate:
Circular (or cyclic) imports in Python

I have class B that imports and creates instances of class A. Class A needs reference to B in its contructor and so includes B.

from a import A
class B:
  def __init__(self):
    self.a = A()

from b import B
class A:
  def __init__(self, ref):
    assert isinstance(ref, B)
    self.ref = ref

This doesn't work. The main file imports B and uses it... not. Something with the imports is wrong.

Error from file a ImportError: cannot import name B

Community
  • 1
  • 1
HWende
  • 1,705
  • 4
  • 18
  • 30

3 Answers3

20

Apart from "don't do that, you are painting yourself into a corner", you could also postpone the import of B until you need it. File a.py:

class A:
    def __init__(self, ref):
        from b import B
        assert isinstance(ref, B)
        self.ref = ref

Class B won't be imported until you instantiate class A, by which time the module already has been imported fully by module b.

You can also use a common base class and test for that.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks, I will go with that. I somewhere saw this idea but couldn't understand. Your additional explanation is excellent! – HWende Apr 05 '12 at 10:49
3

Just import classes in __init__ method

class A:
   def __init__(self, ref):
      from b import B
      assert isinstance(ref, B)
      self.ref = ref
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Ildus
  • 143
  • 8
1

The __init__ method executes when you create an instance of the class. In this case, you should get it to work by simply changing the import statements like this:

import a 
class B:
  def __init__(self):
    self.a = a.A(self)

import b
class A:
  def __init__(self, ref):
    assert isinstance(ref, b.B)
    self.ref = ref
Janne Karila
  • 24,266
  • 6
  • 53
  • 94