Reputation: 85
I have this package structure
project/
package_a/
__init__.py
subpackage_b/
__init__.py
module_one.py
subpackage_c
__init__.py
module_two.py
package_b/
module_one.py
def test_func():
return 0
How can I import test_func
from module_two.py? I have tried using
from subpackage_b.module_one import test_func
from package_a.subpackage_b.module_one import test_func
from module_one import test_func
but none of them works, giving me ModuleNotFoundError
. I understand there are many similar questions here but none of them seems to work for me. One which I have not tried is setting the PYTHONPATH
variable, but I am not sure what to set it to. I am using VSCode and the current python.pythonPath
is just the python file in my venv folder.
Upvotes: 1
Views: 1320
Reputation: 1004
The root is of course your sys.path
, and to answer why it does not work for you, I'll assume you attempt to invoke a python file from within your package, which will not allow python to find your package root properly.
Instead, invoke your code from a file directly in your project root (so the package is in the same directory as your main script file).
From https://docs.python.org/3/library/sys.html#sys.path
As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter.
$ tree
.
├── main.py
└── package_a
├── __init__.py
├── subpackage_b
│ ├── __init__.py
│ └── module_one.py
└── subpackage_c
├── __init__.py
└── module_two.py
# cat main.py
import package_a.subpackage_c.module_two
# cat package_a/subpackage_b/module_one.py
def test_func():
return 0
# cat package_a/subpackage_c/module_two.py
from package_a.subpackage_b.module_one import test_func
print("test func:", test_func())
$ python package_a/subpackage_c/module_two.py
Traceback (most recent call last):
File "package_a/subpackage_c/module_two.py", line 1, in <module>
from package_a.subpackage_b.module_one import test_func
ModuleNotFoundError: No module named 'package_a'
$ python main.py
test func: 0
Upvotes: 0
Reputation: 2117
In python, When the interpreter executes the import
statement, it searches for module in a list of directories assembled from the following sources:
PYTHONPATH
environment variable, if it is set. (The format for PYTHONPATH
is OS-dependent but should mimic the PATH
environment variable.)/usr/local/lib/python
)In addition, You can put the module file in any directory of your choice and then modify sys.path
at run-time so that it contains that directory but this would not be a standard. you can do it for internal purpose but not a best practice to share your code with this.
Rather you can use python's __file__
attribute, to get the path and put it in sys.path
like below:
import sys
from os.path import dirname
sys.path.append(dirname(__file__))
Upvotes: 0
Reputation: 3305
You can find the set of paths that you can import from using
import sys
print(sys.path)
So, make sure that the project path is in sys.path
. If it is not, then you can add it dynamically in your code with the following line, which should be run before your import statements
sys.path.append('C:/Path_to_project/project')
However, if you were running python from the project folder, the path should already be there.
The proper way to import when your sys.path
is including your project folder, would be
from package_a.subpackage_b.module_one import test_func
Upvotes: 2