4

Basically I have the problem of circular dependencies and I can not change to class structure of the code I am working with ( Please don't suggest to change the class structure).

Now I could put all my code into one giant file, but that does not seem practical.

So is it possible that all my classes live in the same namespace, so that this would be possible:

File a.py:

from b import B
class A:
    def foo(self):
        B().bar()

    def bar(self):
        print("Hello, this is A")

File b.py:

from a import A
class B:
    def foo(self):
        A().bar()

    def bar(self):
        print("Hello, this is B.")

Without python exploding in on itself.

  • 3
    As a quick workaround, you may move import statements inside `foo` methods. Anyway, I guess it's a classic [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), but it's hard to tell due to simplification of example. – Łukasz Rogalski Feb 02 '16 at 14:18
  • Possible duplicate of [Avoiding circular (cyclic) imports in Python?](http://stackoverflow.com/questions/13867676/avoiding-circular-cyclic-imports-in-python) – Eric Renouf Feb 02 '16 at 14:22
  • Yeah I thought about that, but I would have to sprinkle those everywhere and also into the constructor of one class, which would lead to the same circular dependency again. –  Feb 02 '16 at 14:22
  • @EricRenouf It is not a duplicate, because the solution provided in that example does not work here. I will update my post to show why not. –  Feb 02 '16 at 14:23
  • 2
    *"I can not change to class structure of the code I am working with ( Please don't suggest to change the class structure)"* - please explain **why not**. – jonrsharpe Feb 02 '16 at 14:37
  • Did you try your example? I believe that this particular code would work. -- if you import one of the files from the main module, which should be neither a.py nor b.py. But other examples might not. – Terry Jan Reedy Feb 02 '16 at 23:05

2 Answers2

2

If you can't change the file structure and/or class hierarchy, you could just move the import lines to a place where they don't end up importing each other. They'd get executed many times, but if you don't mind the performance impact of that you could move the import lines to inside the foo definitions like

class A:
    def foo(self):
        from b import B
        B().bar()

and the analog on the B side.

Probably refactoring is the better way to go, or use the qualified names as @RonaldOussoren shows in his answer.

Eric Renouf
  • 13,950
  • 3
  • 45
  • 67
1

It is not possible to have two modules that share the same namespace. What you can do in your example is to use import a instead of from a import A and then reference the class as a.A (and likewise for class B in the other module).

Ronald Oussoren
  • 2,715
  • 20
  • 29