0

Suppose I have a python module set out as follows:

setup.py
tpkg/
    __init__.py
    module1.py
    module2.py

where __init__.py is:

from .module1 import class1
from .module2 import class2

module1.py is:

from .module2 import class2

class class1(object):
    def __init__(self):
        self._who = "Class 1"

    def __str__(self):
        return "I'm {}".format(self._who)

    def otherclass(self):
        print(str(class2()))

module2.py is:

from .module1 import class1

class class2(object):
    def __init__(self):
        self._who = "Class 2"

    def __str__(self):
        return "I'm {}".format(self._who)

    def otherclass(self):
        print(str(class1()))

and setup.py is:

from setuptools import setup

setup(name="tpkg",
      version="0.0.1",
      packages=["tpkg"])

So, here both the modules need to import the class that is contained in the other module.

If I install this module and try to import tpkg I get the error

In [1]: import tpkg
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-834a70240c6c> in <module>()
----> 1 import tpkg

build/bdist.linux-x86_64/egg/tpkg/__init__.py in <module>()

build/bdist.linux-x86_64/egg/tpkg/module1.py in <module>()

build/bdist.linux-x86_64/egg/tpkg/module2.py in <module>()

ImportError: cannot import name class1

So, my question is, how should I actually go about importing the classes from the two modules into each other?

Update This question is slightly different to that given here, which asks why there is a problem with cyclic imports, rather than the question of how to solve the problem of cyclic imports, which is what I needed.

Matt Pitkin
  • 3,989
  • 1
  • 18
  • 32
  • Possible duplicate of [Cyclic module dependencies and relative imports in Python](https://stackoverflow.com/questions/6351805/cyclic-module-dependencies-and-relative-imports-in-python) – Ivan Nov 21 '17 at 15:55
  • @Ivan. That question only asks **why** the import error happens. This question is asking how to avoid the error. – ekhumoro Nov 21 '17 at 16:02

2 Answers2

1

Moving from relative path import to absolute and from from ... import... syntaxe to import ... (in modules files) should fix your problem

__init__.py

from tpkg.module2 import class2
from tpkg.module1 import class1

module1.py

import tpkg.module2

class class1(object):
    def __init__(self):
        self._who = "Class 1"

    def __str__(self):
        return "I'm {}".format(self._who)

    def otherclass(self):
    print(str(tpkg.module2.class2))

module2.py

import tpkg.module1

class class2(object):
    def __init__(self):
        self._who = "Class 2"

    def __str__(self):
        return "I'm {}".format(self._who)

    def otherclass(self):
        print(str(tpkg.module1.class1))

Test:

>>> import tpkg
>>> c = tpkg.module1.Class1()
>>> c
< tpkg.module1.Class1 object at 0x10535ffd0>
>>> c.otherclass()
<class 'tpkg.module2.Class2'>
>>>
olricson
  • 301
  • 2
  • 8
  • Indeed my previous answer was stupid and fixed nothing. But I think my new answer can fix your issue without having to use local import. – olricson Nov 21 '17 at 18:53
1

You should normally try to avoid circular dependencies:

http://stackabuse.com/python-circular-imports/

Otherwise you can try local imports

class class1(object):
def __init__(self):
    self._who = "Class 1"

def __str__(self):
    return "I'm {}".format(self._who)

def otherclass(self):
    from test2 import class2

    print(str(class2()))

test = class1()

test.otherclass()

and

class class2(object):
def __init__(self):
    self._who = "Class 2"

def __str__(self):
    return "I'm {}".format(self._who)

def otherclass(self):
    from test1 import class1
    print(str(class1()))
ziggy jones
  • 401
  • 2
  • 7