1
votes

I am trying to import a module from multiple locations but can't get this to work because relative imports in Python3 have been disabled. I want to do this so users can copy package_1 and run this at the terminal (using main class); while another class is imported into scriptb.py which is a web-application front-end.

-- projectfolder
-- projectfolder/
-- __init__.py
--- package_1/
------ __init__.py
------ subpackage_a/
------ subpackage_a/core/module1.py
------ subpackage_a/__init__.py
------ subpackage_a/core/__init__.py
------ run.py
--- package_2/
----- __init__.py
-- -- scriptb.py

Here at the "package_1/run.py" imports: from subpackage_a.core.module1 import classname

Here are the "package_2/scriptb" imports: package_1.run import classname

However when I run scriptb.py I get the following error in run.py ImportError: No module named 'package_1.core'

Traceback:
File "/directory/package_1/run.py", line 7, in <module>
    from subpackage_a.common.exceptions import Classname
ImportError: No module named 'subpackage_a.common'

Is there a better way to handle this then catching the ImportError exception and defining two import locations in all of the "package_a" modules?

or better than doing this which means importing each module twice

if __name__ == '__main__': 
    from package_1 import classname
else:
    from .package_1 import classname

Thanks

EDIT:

For future reference I had to do this in the subpackages to import other modules in the core folder

try:
    from package_1.core.module1 import classname:
except ImportError:
    from ..core.module2 import classname

as the following only works in main:

if __name__ == '__main__':
    from package_1.core.module1 import classname:
except ImportError:
    from .package_1.core.module2 import classname
2

2 Answers

1
votes

All the sub-directories must have __init__.py if you want to use it as a package. Try to implement the following file structure.

-- projectfolder
-- projectfolder/
-- __init__.py
--- package_1/
------ __init__.py
------ subpackage_a/
-----------__init__.py**********
------ subpackage_a/core/module1.py
-------------------core/
-----------------------__init__.py**********
------ run.py
--- package_2/
----- __init__.py
-- -- scriptb.py

add an __init__.py file to the subpackage_a folder and subpackage_a/core/ folder

EDITED: I think your way of handling this is a better option

if __name__ == '__main__': 
    from package_1 import classname
else:
    from .package_1 import classname
1
votes

Well, as you can see by your folder structure and the uses of "subpackage_a" in "package_1/run.py" and "package_2/scriptb.py", actually, "subpackage_a" is not a subpackage of "package_1". Better adapt your project to the realities and make "subpackage_a" a real package and make it installable into python using distutils or something similar. Then both "run.py" and "scriptb.py" can use it without reverting to any relative import hacks.