I have a folder, which contains two separate folders, one of which holds some python modules, and the other one holds a python script that uses those modules:
parentFolder/
lib/
__init__.py
readFile.py
writeFile.py
folder/
run.py
The __init__.py file is empty. In run.py, I have the following:
from ..lib import readFile
data = readFile('file.dat')
This gives me the error
Traceback (most recent call last):
File "run.py", line 1, in <module>
from ..lib import readFile
ValueError: Attempted relative import in non-package
What am I missing?
You need to add __init__.py files (can be empty) to each of the directories to make them a package. See the documentation for more details.
Related
I have a folder mypackage at the location /mypath/mypackage/, and it contains an __init__.py file which is empty. mypackage contains two python files: packagefile1 and packagefile2, and packagefile2 contains import packagefile1.
When I then call a python script at /myotherpath/script.py which contains import packagefile2, it correctly finds packagefile2, but I get an error :
Traceback (most recent call last):
File "/myotherpath/script.py", line 5, in <module>
from mypackage import packagefile2
File "/mypath/packagefile2.py", line 16, in <module>
import packagefile1
ModuleNotFoundError: No module named 'packagefile1'
However, I don't get this error when I call packagefile2 directly, so it must be because I am not calling the scripts in the mypackage folder.
What is the appropriate way to solve this?
I have read here that the solution is to change import packagefile1 to import .packagefile1, but then I read here that relative imports using . are outdated. So what is the appropriate way to import modules within the same package?
ps: /mypath/ is part of the pythonpath variable (when I command env | grep -i python in bash, it shows PYTHONPATH=:/mypath/).
I've been working on two packages for a few months as an intern, and I'm wrapping it up to deliver it to the next intern to continue working on it.
I'm having problems with accessing the packages from inside a combined folder. My folder structure looks like this:
> final_packages
__init__.py
> stream_converter
__init__.py
matconverter.py
matloader.py
> stream_plotter
__init__.py
bits_params_manager.py
params_manager.py
plotter.py
folder_plots.py
> examples
example4.py
The __init__.py files in stream_converter and stream_plotter just imports all the modules present in each respective folder. The __init__.py file in Final_packages is empty.
I can use the packages from a file which is in the same folder as Final_packages when I include the directory of Final_packages to sys.path. However, if the file is included in the Examples folder, I get the following error:
>> import stream_converter
Traceback (most recent call last):
File "<ipython-input-23-2fa4258586e7>", line 1, in <module>
import stream_converter
File "C:\Users\kalse\OneDrive - Vestas Wind Systems A S\Personal Documents\Work_with_MORIK\Streaming_w_python\python3\Final_packages\stream_converter\__init__.py", line 1, in <module>
import matconverter
ModuleNotFoundError: No module named 'matconverter'
Somehow it seems that the python can't see the modules that are in the same folder as the __init__.py, even though it actually enters __init__.py. I would not expect it to be good practice t define a path inside these __init__.py files, so clearly I'm missing something - Can somebody help me here?
Best regards
This is my folder structure -
From api.py I import IncidentHandler as below -
import data.IncidentHandler
data.IncidentHandler works fine HOWEVER - inside of the IncidentHandler.py I have the below present:
import BrowserHandler
When I run the code from api.py I get this error -
Traceback (most recent call last):
File "api.py", line 9, in <module>
import data.IncidentHandler
File "/User/**mask**/**mask**/**mask**/**mask**/tpptickethandler/src/data/IncidentHandler.py", line 1, in <module>
import BrowserHandler
ModuleNotFoundError: No module named 'BrowserHandler'
When I run the code directly from IncidentHandler.py it is working as expected.
I realised that the solution was in the modular name so I have changed as follows -
import BrowserHandler
to
import data.BrowserHandler
This now works from api.py but NOT from IncidentHandler.py
New Error from IncidentHandler.py
Traceback (most recent call last):
File "IncidentHandler.py", line 1, in <module>
import data.BrowserHandler
ModuleNotFoundError: No module named 'data'
I can see that I may be working against the typical Python principles however facing this issue was quite a unique challenge and I have not found anything on the internet thus far. Could someone please assist me with a solution and/or how to tackle this better next time.
You are trying to organize the modules under different folders, which are packages. For python to recognize a folder as a package, you need to have an __init__.py file under it, it doesn't matter if this file is empty or not, that will let python correctly recognize the folder as a package
https://docs.python.org/3/tutorial/modules.html#packages
example from the official site
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
I've read through a couple of similar questions, notably this one about imp.load_module which seems to be close to what I want, but I can't understand why I'm still getting ImportErrors. Here is my folder hierarchy:
program\
__init__.py
main.py
thirdparty\
__init__.py
css\
__init__.py
css.py
utils\
__init__.py
http.py
In main.py I have the following code. This is intended to search the thirdparty\ directory and load each module it finds. Each module is in its own separate directory.
import os
import imp
for root, dirs, files in os.walk("thirdparty"):
for source in (s for s in files if s.endswith(".py")):
name = os.path.splitext(os.path.basename(source))[0]
m = imp.load_module(name, *imp.find_module(name, [root]))
The problem is that css.py happens to use its own subfolder that it loads stuff off of, utils. It has a line in it that says:
from utils import http
And that is where it fails. I get this error when I run main.py.
Traceback (most recent call last):
File "main.py", line 7, in <module>
m = imp.load_module(name, *imp.find_module(name, [root]))
File "thirdparty/css/css.py", line 1, in <module>
from utils import http
ImportError: No module named utils
I'm stumped. css.py is self contained in its own folder, and when I run css.py separately it imports utils just fine. What is causing this?
Maybe you can solve this by changing the import to:
from .utils import http
Or by adding the folder you import to the Python Path:
sys.path.append(os.path.join(root, source))
When you import modules in thirdparty, the place Python looks for modules is still the main directory. The initial import works, because you give the right path to imp.find_module, but after that Python has no idea where to look for the modules.
This is my folder structure:
src/
__init__py
Lowlevel/
__init__.py
ModuleToCheck.Py
Test/
__init__.py
ModuleToCheck_test.py
(__init__.py are empty files)
Now I want to import ModuleToCheck.py in ModuleToCheck_test.py
How am I able to do this without appending anything to sys.path?
Update:
from ..Lowlevel import ModuleToCheck leads to:
src$ python Test/ModuleToCheck_test.py
Traceback (most recent call last):
File "Test/ModuleToCheck_test.py", line 6, in <module>
from ..Lowlevel import ModuleToCheck
ValueError: Attempted relative import in non-package
The following is from http://docs.python.org/tutorial/modules.html#intra-package-references
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.
You're running your module ModuleToCheck_test.py as the main module, hence the exception.
One solution is to create a test.py module in your src directory containing the following:
import Test.ModuleToCheck_test
You can then run that module using python test.py