My file structure is as follows:
monitor/
core/
database.py
processor.py
timekeeper.py
jobs/
jobA.py
jobB.py
setup.py
From jobA.py I import like this:
from core.database import Database
from core.timekeeper import Timekeeper
from core.processor import Processor
While at database.py, processor.py and timekeeper.py I import setup.py.
Get the following error when I run jobA.py:
root#test:/var/www/python/monitor# python3 jobs/jobA.py
Traceback (most recent call last):
File "jobs/jobA.py", line 2, in <module>
from core.database import Database
ModuleNotFoundError: No module named 'core'
To allow import core or import core.database (without the relative dots or double-dots) the parent directory of core should either be the current directory, or be included on sys.path. You appear to have a setup.py. Conventionally that means a file that performs installation and packaging tasks via the setuptools or distutils packages. If that is indeed the role it performs, perhaps you need to run it. One way to run it would be to issue (from the command-line outside Python) the command pip install -e /path/to/monitor. Assuming setup.py was written correctly, this will ensure that the core package, in its current location, is lastingly made available for the default Python distribution. Next time you launch Python, /path/to/monitor will be on sys.path and import core will work from (almost) anywhere.
Add
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
to the top of your jobA.py file. If you are using python 3.3+, you do not need an __init__.py file. It needs to be above your other import statements.
From this answer you can use 2 dots to import from a directory above. So you could potentially use:
from .core.database import Database
from .core.timekeeper import Timekeeper
from .core.processor import Processor
Python 3.3+ you don’t need an __init__.py file so I don’t believe just adding one will help.
What module are you trying to use? Maybe your module is not compatible with Python 3.
Related
I have a Python library with Cython code.
When I compile the library I manage to import it successfully and use it in other projects. But when I write tests (which are executed from within the library's project root path), there's an import issue and the Cython code cannot be imported.
I have removed the project's path from sys.path so the import system will prefer to import from site-packages, and the import issue indeed occur in site-packages, but still, it happens only when I execute a file under the library's path, but does not happen when I import the library and execute a file under another project path.
Here's the project's structrue:
libname:
-libname/
call_mapping.pyx
main.py (imports call_mapping.pyx)
-tests/
test_libname.py (imports libname, raises ImportError because main.py can't import call_mapping.pyx)
But on another project, the error does not occur:
another-project:
f.py (import libname successfully)
The error:
from libname.main import LibnameSettings
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/libname-0.1.9-py3.10-macosx-10.9-universal2.egg/libname/main.py", line 6, in <module>
from libname.call_mapping import (
ModuleNotFoundError: No module named 'libname.call_mapping'
Any ideas on how to fix this? Thanks!
I am trying to build a Python package. For simplification, I will only mention the parts which are relevant to the problem:
The package (directory) is called moranpycess and inside it there are three relevant files:
The initfile for the whole package __init__.py:
from .Individual import Individual
from .MoranProcess import MoranProcess
A module called Individual which contains a class Individual.
A module called MoranProcess which contains a class MoranProcess. At the top it imports the previous module with: import Individual.
I install the package with python -m pip install .
Then I run a test to see if the package can be imported properly: python -c 'import moranpycess'.
I get:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/runner/work/angry-moran-simulator/angry-moran-simulator/moranpycess/__init__.py", line 18, in <module>
from .MoranProcess import MoranProcess
File "/home/runner/work/angry-moran-simulator/angry-moran-simulator/moranpycess/MoranProcess.py", line 22, in <module>
import Individual
ModuleNotFoundError: No module named 'Individual'
Error: Process completed with exit code 1.
This is strange to me since it seems that the Python interpreter can find the package, the package imports the respective classes but the interpreter also tries to execute the top-level module imports and (I don't know why) it does not find the module...
Am I doing something wrong here?
EDIT:
directory structure:
└── moranpycess
├── Individual.py
├── MoranProcess.py
└── __init__.py
Update
I am considering the solution proposed here:
https://stackoverflow.com/a/49375740/2340598
However I don't know if this is the "right" way to organize a package...
Relative imports are a bit harder to get right than absolute imports. They are also more brittle (e.g., if you move a file doing the import, it breaks), so unless you have a good reason to use relative imports I'd suggest to just use absolute ones.
Following that, your public API as it is defined in your topmost __init__.py would look like this:
from moranpycess.MoranProcess import MoranProcess
__all__ = ["MoranProcess"] # import hint that some tools use
While non-public objects can still be imported internally (e.g. in MoranProcess.py) in the following way:
from moranpycess.Individual import Individual
The good thing about absolute imports is that no matter where in your package (or outside of it) you are, they always look the same.
If done like this, users that have installed your package should be able to use your objects like this:
from moranpycess import MoranProcess # directly gets the object, not module
You should try to avoid messing with sys.path in order to get your imports to work, mainly because it isn't necessary. If all you're doing is writing regular python code that is meant to be used in a regular way, the builtin import mechanics should serve your use cases just fine.
If I were to import a package and noticed that sys.path changed, I'd suspect shenanigans and start looking for an alternative.
I have a few seperate pythone file and I am using them to import another py file. Modules that trying to import them are in seperate folder I code sample is below
from tez.library.image_crop import ImageCrop
from tez.library.image_process import ImageProcess
from tez.library.image_features import ImageFeatures
from tez.const.application_const import ApplicationConst
from tez.library.file_operation import FileOperation
this code is in where I want to start the py file using commond line as "python samples1.py" and thrown an error as below
Traceback (most recent call last): File "samples1.py", line 1, in
from tez.library.image_crop import ImageCrop ModuleNotFoundError: No module named 'tez'
folder structure :
.tez
-- library
---- image_crop.py
---- image_process.py
---- image_features.py
--src
---- samples1.py
Python version : 3.8
Pip : 20.0.2
Windows 10 Pro 1909
If you are building a package called tez (and since you tried to import it I think you are). Then everything with tez needs to refer to itself locally. All the files in the tez package need to refer to each other with the "." and ".." imports.
In samples1.py:
from ..library.image_crop import <something>
EDIT:
It sounds like you are misunderstanding how python imports things. When you run "import X" in a python script, then python looks for a package named X under sys.path. You can append to sys.path at the top of your script if you have a custom package to look for.
import sys
sys.path.append(<directory of tez>)
import tez
However, it is strongly recommended that you should not be importing from a file that is under the directory structure of the package name. If "examples" is a directory of examples that use the package "tez" then "examples" should be located outside the package "tez". If "examples" is inside the package "tez", then "examples" should be doing local imports "with-in" the package.
Getting a handle on package use can be tricky.
sample.py can't see above of src folder, but you can tell Python to do this.:
import sys
import os
tez = os.path.dirname(os.path.dirname(__file__))
# __file__ is path of our file (samples.py)
# dirname of __file__ is "src" in our state
# dirname of "src" is "tez" in our state
sys.path.append(tez) # append tez to sys.path, python will look at here when you try import something
import library.image_crop # dont write "tez"
But this is not a very good design I think.
I am getting this error
Traceback (most recent call last):
File "Exporter.py", line 3, in <module>
import sys,getopt,got,datetime,codecs
File "C:\Users\Rohil\Desktop\GetOldTweets-python-master\got\__init__.py", line 1, in <module>
import models
ModuleNotFoundError: No module named 'models'
my directory tree is:
C:\Users\Rohil\Desktop\GetOldTweets-python-master\got
this contains 2 folders: manager and models and 1 __init__.py file with the code :
import models
import manager
i am executing a file with the path: C:\Users\Rohil\Desktop\GetOldTweets-python-master\Exporter.py
I can't figure out what the issue is. can anyone assist me?
Set the environment variable PYTHONPATH=C:\Users\Rohil\Desktop\GetOldTweets-python-master\got (how exactly, depends on your operating system)
If you have created a directory and sub-directory then follow the below steps and please keep in mind that a directory must have an __init__.py file for python to recognize it as a package.
First run this to see all paths being searched by python:
import sys
sys.path
You must be able to see your current working directory in that list.
Now import the sub-directory and the respective module that you want to use via the import command: import subdir.subdir.modulename as abc You should now be able to use the methods in that module.
As you can see in this screenshot above I have one parent directory and two sub-directories. Under the second sub-directory I have a module named CommonFunction. On the console to the right you can see my working directory after execution of sys.path.
Does the models folder has an __init__.py file inside it ? Only then, it will be recognized as a module by python and import models would make sense.
So,
Create an empty __init__.py file in the models subfolder and then the code should work without any issues.
You should also look at this answer.
if create d or using or custom python package
check our dir. correct.
** For python 3.7 user **
from. import module_name
If you are using python3 but are installing the API through 'pip install 'such and such'. It's not gonna work on python3 console. Therefore, you'd better use 'sudo python3 -m pip install 'such and such''. Then it's gonna work!
(at least for ubuntu stuff)
:)
I'm still learning to code better in Python. Therefore I am trying to use some constructions in my programming. Things like name_conventions and structured packaging & modules.
That said I come across an issue which I cannot resolve, it seems.
The structure I chose is as follows:
Core
__init__.py
controller.py
Dashboard
Log
Plugins
Stats
__init__.py
controller.py
Plugin2
Plugin3
Etc..
main.py
In the Core controller.py i am trying to import the Stats(object) class.
I have tried several different ways. In my IDE (Pycharm) it works like a charm ;) When i try to start it via Command Line i get ImportErrors.
I have tried different approaches.
from Plugins.Stats.controller import Stats
from Plugins.Stats import controller
from Plugins.Stats import controller.Stats
from Plugins import Stats.controller
I also tried to put the Stats class into the Plugins.Stats.__init__.py and call it:
from Plugins.Stats import Stats
and I get this:
Traceback (most recent call last):
File "controller.py", line 4, in <module>
from Plugins.Stats.controller import Stats
ImportError: No module named 'Plugins'
The funny thing is... When i try to do the same from main.py.
It does work. So I am really confused. Am I doing something wrong?
Also are there special design patterns to handle imports?
You should add __init__.py file also in the Plugins directory so it will look like
Plugins
__init__.py
Stats
__init__.py
controller.py
You can read more about Python modules here - check out 6.4. Packages
you also can make your module you want to import visible for everyone by adding it to the pythonpath
sys.path.append("/path/to/main_folder")
before this modules are on another namespaces
You will find more info here
First put From plugin import stats, then from stats import controller and import _init_
Incase of running from the terminal it will only try to import from the current folder. You have to manually add the path of the main folder to this file using the following code at the beging of the file
import sys
sys.path.append("../")
If you want to back 2 folders add ../../ instead of ../
You should not start a submodule of a package directly as a script. This will mess up your hierarchy most of the time. Instead call it as a module:
python -m Core.controller
You can verify the following by adding this to the top of any of your scripts:
import sys
for p in sys.path:
print(repr(p))
The reason the imports work when invoked as:
python main.py
is python will add the directory of the script to the pythonpath (In this case the empty string '')
However, when running
python Core/controller.py
it will add Core to sys.path, rendering the rest of your project unimportable
You can instead use
python -m Core.controller
which'll invoke using runpy and again put the empty string on the python path.
You can read more about invocation options of the python interpreter here: https://docs.python.org/2/using/cmdline.html You can read about runpy here: https://docs.python.org/2/library/runpy.html