Declaring A Class And Subclass In Two Different Files In Python
Solution 1:
The problem is easy to understand if you look at how Python loads modules:
- You run
python file2.py
. - Python loads
file2.py
and starts to execute it. - Python parses
from file1 import superclass
. - Python loads
file1.py
and starts to execute it. - Python parses
from file2 import subclass
. - As
file2
is already loaded, Python tries to accessfile2.subclass
. - Python didn't yet parse the class statement, so
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.
class superclass:
def __init__(self):
"Stuff"
def method(self):
from file2 import subclass
temp = subclass()
"Stuff"
This causes the import to happen when method
is called for the first time and not while importing/loading file1
.
The downside is that there is some runtime overhead every time method
is called and that you must make sure that method()
is only called after the import of file1
was completed.
2) import file2
at the end of file1
without using from import
.
class superclass:
def __init__(self):
"Stuff"
def method(self):
temp = file1.subclass()
"Stuff"
import file2
This way the circular import of file2
happens when superclass
already exists in the namespace of file1
. At that time the namespace of file2
is incomplete (file2.subclass
doesn't exist yet, so from file2 import subclass
would fail) but as long as method
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 cause ImportErrors
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.
Solution 2:
Get temp
from a method and override that method in the subclass.
class superclass:
def get_temp(self):
return 'a superclass temp'
def method(self):
temp = self.get_temp()
print(type(self).__name__, repr(temp))
class subclass(superclass):
def get_temp(self):
return 'a subclass temp'
superclass().method()
subclass().method()
Output:
superclass 'a superclass temp'
subclass 'a subclass temp'
If you need method()
to be different in subclass
or perhaps do some work before or after superclass.method()
, use the super keyword.
Solution 3:
You can include the following line into your file2:
if superclass in locals(): print pass
else: 'Please define superclass'
Like this:
File2:
from file1 import superclass
class subclass(superclass):
if superclass in locals(): pass
else: print 'Please define superclass'
def __init__(self):
"Stuff"
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:
x = superclass()
The subclass becomes workable.
Post a Comment for "Declaring A Class And Subclass In Two Different Files In Python"