I have two files, one declaring a superclass which involves a method involving a subclass, and the other defining the subclass.
File1:
from file2 import subclass
class superclass:
def __init__(self):
"Stuff"
def method(self):
temp = subclass()
"Stuff"
File2:
from file1 import superclass
class subclass(superclass):
def __init__(self):
"Stuff"
When I run file1's code I get an error inside file2 that superclass is not defined. This is because I import file2 before defining the superclass.
However if I import file2 after defining superclass I get an error in file1 saying the subclass is not defined. This is because I use a subclass instance in the method.
One solution to this problem is to have both superclass and subclass declarations in a single file, but I am wondering if there is a way to have them declared in different files.
You can include the following line into your file2:
Like this:
File2:
Now try to run the file1 NOT file2. It will prompt 'Please define superclass'. But the subclass has been registered. Once you run something like:
The subclass becomes workable.
Get
temp
from a method and override that method in the subclass.Output:
If you need
method()
to be different insubclass
or perhaps do some work before or aftersuperclass.method()
, use the super keyword.The problem is easy to understand if you look at how Python loads modules:
python file2.py
.file2.py
and starts to execute it.from file1 import superclass
.file1.py
and starts to execute it.from file2 import subclass
.file2
is already loaded, Python tries to accessfile2.subclass
.subclass
doesn't exist yet. This causes theImportError
.Python can handle circular dependencies as long the classes are already parsed when the second import happens. There are two ways to get that:
1) import
file2
in the method itself.This causes the import to happen when
method
is called for the first time and not while importing/loadingfile1
. The downside is that there is some runtime overhead every timemethod
is called and that you must make sure thatmethod()
is only called after the import offile1
was completed.2) import
file2
at the end offile1
without usingfrom import
.This way the circular import of
file2
happens whensuperclass
already exists in the namespace offile1
. At that time the namespace offile2
is incomplete (file2.subclass
doesn't exist yet, sofrom file2 import subclass
would fail) but as long asmethod
is never called before the imports succeeded, it works. The downside is that you need to keep track of which import statements need to be at the bottom of the file and which need to be at the top. Any error will causeImportErrors
that can be hard to track if your module hierarchy gets more complex.That said, you should really rework your class hierarchy. Circular imports are (as I explained above) very fragile and should generally be avoided.