Imports don't work using java like packaging - python

I am developing a project which has a directory structure like this:
projectName
package1
module1.py
package2
module2.py
I am developing in Eclipse-PyDev and in module1.py i import module2 using this statement:
import projectName.package2.module2
when i want to execute module1 I do:
cd projectName
python package1.module1
but it can not import module2 giving this error:
ImportError: No module named projectName.package2
I'm new to Python and want to know the best practices for packaging and importing.
what i'm doing know is to put module2 in projectName directory and to remove projectName from all imports. This way i can execute the modules. But i have to change the file everytime i copy the development program into the deployment server.

Related

Python module not found when calling from another

I have this project structure:
/project_name
main.py
----- __init__.py
------ /modules
-------- __init__.py
-------- module1.py
-------- module2.py
I've edited to add more information. After working and testing a lot of recomendations to solve the problem, nothing works.
Enviroment
Windows
Conda virtual enviroment project python 3.10
VSCode
Problem
When running main.py from VScode
from modules.module1 import *
if __name__ == "__main__":
pass
this error raise
from module1 import *
ModuleNotFoundError: No module named 'module2'
Modules
module1.py
from module2 import *
module2.py
def test():
print("just testing")
So the problem always occurs when from main.py i import a module that imports another module. The second module imported from the module that i have imported from main.py is not found.
Still looking for the solution
You could try to set PythonPath first. If you use vscode to develop, you could set this PythonPath in setting.json
if module1.py and module2.py are in the same directory, you could try to use relative import. Please pay attention to cycle import as well.
from .module1 import Module1
main.py had better to move into src directory.
Pycharm working directory
If you use Pycharm, you can configure the run configuration working directory to the root of your project.
Import your package in editable mode
Create a pyproject.toml file in the root of the project with this content:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "package_name"
version = "0.0.1"
requires-python = ">=3.7"
Your package need to follow this structure:
project_name/
└── src/
└── package_name/
├── __init__.py
└── example.py
To install it in your environment from the root of the project:
user/projects/package_name$ pip install -e .
By doing that, you won't have to worry about PYTHONPATH, workind directory, relative/absolute import. You just import and use your package using the intended path you created, Python will know how to look thanks of the pip install command.
run the file from project_name folder
If you run a file from inside a folder, python will be able to look local module from this folder. You need to call it at the root of the project.
user/projects/package_name$ python -m src/modules/module2.py
Thanks all. Finally i've solved it including this line before importing my file module:
sys.path.append("X:\\path\\root_folder\\")

Having trouble making relative imports in sibling directories

Im having trouble importing from sibling directories.
I would like to set up my package so that all of these aspects simultaneously work.
Here is my module setup:
package/
__init__.py
code/
__init__.py
model.py
helper.py
notebooks/
__init__.py
notebook1.ipynb
Imports in model.py:
from helper import *
When running from the command line in package/ I set PYTHONPATH=. and I can run model.py
Imports in notebook1.ipynb:
First scenario:
sys.path.insert(0, os.path.abspath('..'))
from code.model import MetaModel
Results in: ModuleNotFoundError: No module named 'code.model'; 'code' is not a package
Second scenario:
sys.path.insert(0, os.path.abspath(os.path.join('../code')))
from model import MetaModel
This works. Why can I not use the first scenario.

Python: importing a sub-package module from both the sub-package and the main package

Here we go with my first ever stackoverflow quesion. I did search for an answer, but couldn't find a clear one. Here's the situation. I've got a structure like this:
myapp
package/
__init.py__
main.py
mod1.py
mod2.py
Now, in this scenario, from main.py I am importing mod1.py, which also needs to be imported by mod2.py. Everything works fine, my imports look like this:
main.py:
from mod1 import Class1
mod2.py:
from mod1 import Class1
However, I need to move my main.py to the main folder structure, like this:
myapp
main.py
package/
__init.py__
mod1.py
mod2.py
And now what happens is that of course I need to change the way I import mod1 inside main.py:
from package.mod1 import Class1
However, what also happens is that in order not to get an "ImportError: No module named 'mod1'", I have make the same type of change inside mod2.py:
from package.mod1 import Class1
Why is that? mod2 is in the same folder/pakcage as mod1, so why - upon modifying main.py - am I expected to modify my import inside mod2?
The reason this is happening is because how python looks for modules and packages when you run a python script as the __main__ script.
When you run python main.py, python will add the parent directory of main.py to the pythonpath, meaning packages and modules within the directory will be importable. When you moved main.py, you changed the directory that was added to the pythonpath.
Generally, you don't want to rely on this mechanism for importing your modules, because it doesn't allow you to move your script and your package and modules are only importable when running that main script. What you should do is make sure your package is installed into a directory that is already in the pythonpath. There are several ways of doing this, but the most common is to create a setup.py script and actually install your python package for the python installation on your computer.

py2exe executing error

I have a dir structure .
location of dir is "d:\sources\dir"
/dir
__init__.py
commonlibs/
__init__.py
lib1.py
lib2.py
project1/
__init__.py
prgfile1.py
prgfile2.py
prglib/
__init__.py
prglib1.py
prglib2.py
when i add dir to my PYTHONPATH i can easily import from anything and run the python script.
but when i create my exe from py2exe i get import error of modules present in "commonlibs".
and these modules are imported in prglib1 modules. and some other modules are not imported.
i dont know what i am missing ,but at the end i want to import from any where and my exe should run without error. my exe is an windows service and my project has named pipe implemented.

Import Script from a Parent Directory

How do I import a module(python file) that resides in the parent directory?
Both directories have a __init__.py file in them but I still cannot import a file from the parent directory?
In this folder layout, Script B is attempting to import Script A:
Folder A:
__init__.py
Script A:
Folder B:
__init__.py
Script B(attempting to import Script A)
The following code in Script B doesn't work:
import ../scriptA.py # I get a compile error saying the "." is invalid
You don't import scripts in Python you import modules. Some python modules are also scripts that you can run directly (they do some useful work at a module-level).
In general it is preferable to use absolute imports rather than relative imports.
toplevel_package/
├── __init__.py
├── moduleA.py
└── subpackage
├── __init__.py
└── moduleB.py
In moduleB:
from toplevel_package import moduleA
If you'd like to run moduleB.py as a script then make sure that parent directory for toplevel_package is in your sys.path.
From the docs:
from .. import scriptA
You can do this in packages, but not in scripts you run directly. From the link above:
Note that both explicit and implicit relative imports are based on the
name of the current module. Since the name of the main module is
always "__main__", modules intended for use as the main module of a
Python application should always use absolute imports.
If you create a script that imports A.B.B, you won't receive the ValueError.
If you want to run the script directly, you can:
Add the FolderA's path to the environment variable (PYTHONPATH).
Add the path to sys.path in the your script.
Then:
import module_you_wanted

Categories