3

PLEASE READ BEFORE MARKING AS DUPLICATE

I have a a directory configured as such:

app.py  
Modules/  
    __init__.py  
    a.py  
    b.py  

Where _init_.py contains:

import a  
import b

and a.py contains:

import b
Class A():
    b_instance = b.B()`

and b.py contains:

import a
Class B():
    a_instance = a.A()`

This entire /Modules folder is imported from the main app.py.

It is my understanding that the execution will go as follows:

  1. app.py import Modules
  2. /Modules/_init_.py import a
  3. /Modules/a.py import b
  4. /Modules/b.py import a (sees that a is already in sys.modules and continues)
  5. /Modules/b.py executes Class B() and fails when trying to do: a_instance = a.A() because while a.py is in sys.modules, it has not yet executed class A and thus b.py cannot access Class A

How then, can I have two classes which depend on each other and that dependency is linked at the highest scope of the class (i.e. not within a class method)?

The solutions given online assume that the class dependency occurs within some sub method which fixes the issue because the actual class is not needed until that specific function is executed. The difference of my issue is that the class dependency is directly in the Class, not within some method, so the actual class is needed immediately.

brandonscript
  • 68,675
  • 32
  • 163
  • 220
James
  • 445
  • 1
  • 6
  • 19
  • That post is most likely when a dependency is within a method that is not executed immediately. As you can see, I am doing absolute imports anyway and the issue persists because the class instances are not within a method and are thus executed immediately. So the error then becomes not that you can't import a or import b, but that execution fails once reaching the call to a.A() because class A is not defined – James Aug 29 '18 at 13:25
  • Do you actually need a class-level property (`A.b_instance`) or would an instance-level property suffice (`a = A(); a.b_instance`)? If you need a class-level property, I would use a proxy object that lazily constructs an instance, rather than eagerly constructing. But first I would try to figure out a way to avoid requiring a static circular dependency in the first place -- possibly `A` and `B` objects should be constructed using a factory method or something like that. – Daniel Pryden Aug 29 '18 at 14:36
  • I'm using arango-orm for arangodb. That package has a class called Relation() that links objects together based on some key (link A to B). This orm doesn't seem to be written the best, per say, and I think it requires that the Relation be declared at class-level. It also requires specifying the exact class, so a factory method won't work (*based off of wikipedia knowledge on factory methods). – James Aug 29 '18 at 15:26
  • I was able to just avoid the circular dependency by adding these class-level instances of the other class outside of the class definition. So I declare Class A, then import class B, then add A.b = B() to the A class. Definitely a temporary solution. – James Aug 29 '18 at 15:28

0 Answers0