(Solved)
This link https://dev.to/codemouse92/dead-simple-python-project-structure-and-imports-38c6 explains Python structure and imports well, too.
I have created a Python package test_pkg.
test_pkg/
├── setup.py
└── test_pkg
├── __init__.py
├── main.py
└── sub_pkg
├── __init__.py
└── sub_pkg_a.py
In the main.py, a module from a sub-package will be imported,
but I have to explicitly write:
from test_pkg.sub_pkg import sub_pkg_a
Otherwise, if I only write:
from sub_pkg import sub_pkg_a
Python will report:
>>> import test_pkg.main
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/zheng/tests/test_pkg/test_pkg/main.py", line 2, in <module>
from sub_pkg import sub_pkg_a
ModuleNotFoundError: No module named 'sub_pkg'
Could you tell me why the package name is required: test_pkg.sub_pkg?
The relative import works fine with the package, but if I execute the main.py script directly, there will be another import error:
~/tests/test_pkg/test_pkg$ python3 main.py
Traceback (most recent call last):
File "main.py", line 2, in <module>
from .sub_pkg import sub_pkg_a
ModuleNotFoundError: No module named '__main__.sub_pkg'; '__main__' is not a package
So, the question is: paths of __init__.sub_pkg and __main__.sub_pkg are different?
What you need to use here is relative import.
Try running the same thing with
from .sub_pkg import sub_pkg_a
The dot in this case refers to "relative to the file that import is in", in this case relative to the location of main.py
This article explains it pretty nicely https://realpython.com/absolute-vs-relative-python-imports/
Related
This doesn't seem to be an issue in python 3 but I'm needing to use python 2.7 for this and get the following issue
DIRECTORY STRUCTURE
module
├── __init__.py
└── submodule
├── __init__.py
└── test.py
# module/__init__.py
from module import submodule
# module/submodule/__init__.py
from module.submodule import test
# module/submodule/test.py
from module import submodule
when I try to import module from somewhere else it results in the following error:
>>> import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "module/__init__.py", line 1, in <module>
from module import submodule
File "module/submodule/__init__.py", line 1, in <module>
from module.submodule import test
File "module/submodule/test.py", line 1, in <module>
from module import submodule
ImportError: cannot import name submodule
I'm assuming the issue has something to do with circular imports but i need to use submodule in both module/__init__.py and module/submodule/test.py
any help is appreciated
As you've mentioned circular imports, one way to resolve this is by importing the module locally.
For e.g.
def fun():
from module import submodule
I've got a project with the following structure:
\main_model
__init__.py
main.py
\second_module
__init__.py
second.py
\third_module
__init__.py
third.py
second_module and third_module are both Git submodules used as libraries by many other projects.
The first line of main.py is an import statement: from main_model.second_module import second
And the first line of second.py is too: from second_module.third_module import third
Running main.py raises an error with the following Traceback:
Traceback (most recent call last):
File "/main_model/main.py", line 1, in <module>
from main_model.second_module import func_a, func_b
File "/main_model/second_module/second.py", line 1, in <module>
from third_module.third import func_c, func_d
ModuleNotFoundError: No module named 'third_module'
So evidently I would need to amend the import statement in second.py to be from main_model.second_module.third_module import third. I can't do that, though, because second_module is a standalone submodule.
Is there a consistent way of structuring the imports, or modifying PYTHONPATH, that would allow the same import syntax from all levels?
I have a file hierarchy of a python package, "try_from_import", like this:
.
├── __init__.py
├── fibo.py
└── test
└── __init__.py
Within the directory "test", I cannot import the module fibo.py:
In [1]: from .. import fibo
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-94aab0998156> in <module>
----> 1 from .. import fibo
ImportError: attempted relative import with no known parent package
How can I import the module fibo from the folder "test"? I am using python 3.7 on a Mac OS if that matters.
[update] Following the advice in the comments, "do not run python from within the package", I tried to run a file test/test.py which contains "from .. import fibo" from outside the package named "try_from_import". But I still got the error:
% python try_from_import/test/test.py
Traceback (most recent call last):
File "try_from_import/test/test.py", line 1, in <module>
from .. import fibo
Getting error “Attempted relative import in non-package” even with init.py.
pkg/
__init__.py
conf/
core.py
__init__.py
scripts/
core_script.py
__init__.py
In core_script.py I have the following import statement
from ..conf.core import gDocsCred
However, when I run, I get the following error:
scripts$ python core_test.py
Traceback (most recent call last):
File "core_script.py", line 3, in <module>
from ..conf.core import gDocsCred
ValueError: Attempted relative import in non-package
The problem was there because I was not using it as a package.
python -m pkg.scripts.core_script
I have a script hello.py which can be used as a module by main.py, or be called from the command line. It itself imports a module helper.py which is in the same directory:
├── lib
│ ├── hello.py
│ ├── helper.py
│ ├── __init__.py
├── main.py
The contents of the files are
$ cat main.py
import lib.hello
lib.hello.sayhi()
------------------------------------
$ cat lib/hello.py
import helper
def sayhi():
print("bonjour")
print(helper.something())
if __name__ == "__main__":
print("hello")
------------------------------------
$ cat lib/helper.py
def something():
print("something")
The problem I have is that hello called from the command line works fine (imports helper.py correctly as it is at the same leval as hello.py) but when running main.py I get
$ python3 main.py
Traceback (most recent call last):
File "main.py", line 1, in <module>
import lib.hello
File "/tmp/lib/hello.py", line 1, in <module>
import helper
ImportError: No module named 'helper'
because from the perspective of main.py, helper.py is in lib.
If I change the import in hello.py to import lib.helper then I have the same problem the other way round:
$ python3 hello.py
Traceback (most recent call last):
File "hello.py", line 1, in <module>
import lib.helper
ImportError: No module named 'lib'
How do I get out of this catch 22 situation?
I suspect that the information from "PEP 338 -- Executing modules as scripts" could be useful but I fail to understand how to bring them in practice to my problem.
you should set in hello.py
import lib.helper
and in the call of do something method:
lib.helper.something()
That solves your problem, you can call main or hello without problems