Reputation: 47
I've looked at so many stackoverflow posts but I don't understand why I'm getting this problem
My file system
parent_folder
|folder1
|module1.py
|module2.py
|__init__.py
|folder2
|main.py
I want to import module1.py and module2.py into main.py.
My __init__.py file has the following
__all__=['module1','module2']
Here is what I'm trying in main.py
from ..folder1 import *
But this give me this error:
Traceback (most recent call last):
File "main.py", line 2, in <module>
from ..folder1 import *
SystemError: Parent module '' not loaded, cannot perform relative import
I've been trying to solve this for an hour and nothing is working. Please help.
edit: I solved this by using absolute path (nothing else was working)
Upvotes: 0
Views: 4109
Reputation: 3041
Here is what I came up as a solution:
To make is flexible to called from child folders and parent folder
import importlib
import sys
class MyClass:
def __init__(self):
sys.path.append('../folder1/')
sys.path.append('../../folder1/')
When you need to use a class from an external a module, use something like this:
mod = importlib.import_module('MyExternalModule')
my_object = getattr(mod, 'MyExternalClass')
This is to answer to @noobycoder, but maybe is not the best practice. The best approach is to create a package for the external module and installed in your python environment.
Upvotes: 0
Reputation: 4191
Relative imports works with respect to your package.
When you run python main.py
simply it cant find what is current package
considering your path to parent folder is /path/up/to/parent_folder
execute
python -m parent_folder.folder2.main from /path/up/to
OR
set PYTHONPATH
or sys.path
to /path/up/to/parent_folder
, then change import to following
from folder2 import *
and execute python main.py
UPDATE
One of relative imports use case is to consume your package
from script outside the package. This script usually acts as entry point or executable.
following is an example directory structure
myapp
│ entry.py
│
└───package
│ __init__.py
│ __init__.pyc
│
├───folder1
│ module1.py
│ __init__.py
│
└───folder2
start.py
__init__.py
myapp/entry.py:
import sys
from package.folder2 import start
if __name__ == '__main__':
sys.exit(start.main())
myapp/folder2/start.py:
import sys
from ..folder1.module1 import *
# this is relative import to "package".
# Use?: It will avoid confusion and conflicts with other packages in your syspath. Improve readability at some extent,
def main():
print "do something with folder1.module1 imported objects"
and $ python entry.py
Upvotes: 1
Reputation: 926
I do it like this in python webapp2. Let me know if it helps.
from folder1.module1 import module1 #i did not try * but i hope it will also work.
from folder1.module2 import module2 #i did not try * but i hope it will also work.
Upvotes: 1
Reputation: 263
I prefer that you transfer folder1
to folder2
and then try
from folder1 import *
or maybe if you want keep the folders in that way you can try
import sys
sys.path.append("../") # or maybe sys.path.append("..")
from folder1 import *
this will add folder1
to your system path
if you don't want to add to system path try
import os
os.chdir("../") #or maybe os.chdir("..")
from folder1 import *
I hope this the solution to your problem
Upvotes: 0