TL;DR: You can't do relative imports from the file you execute since __main__ module is not a part of a package.
Absolute imports - import something available on sys.path
Relative imports - import something relative to the current module, must be a part of a package
If you're running both variants in exactly the same way, one of them should work. Here is an example that should help you understand what's going on. Let's add another main.py file with the overall directory structure like this:
.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py
And let's update test.py to see what's going on:
# config.py
debug = True
# test.py
print(__name__)
try:
# Trying to find module in the parent package
from . import config
print(config.debug)
del config
except ImportError:
print('Relative import failed')
try:
# Trying to find module on sys.path
import config
print(config.debug)
except ModuleNotFoundError:
print('Absolute import failed')
# main.py
import ryan.test
Let's run test.py first:
$ python ryan/test.py
__main__
Relative import failed
True
Here "test" is the __main__ module and doesn't know anything about belonging to a package. However import config should work, since the ryan folder will be added to sys.path.
Let's run main.py instead:
$ python main.py
ryan.test
True
Absolute import failed
And here test is inside of the "ryan" package and can perform relative imports. import config fails since implicit relative imports are not allowed in Python 3.
Hope this helped.
P.S.: If you're sticking with Python 3 there is no more need for __init__.py files.
TL;DR: You can't do relative imports from the file you execute since __main__ module is not a part of a package.
Absolute imports - import something available on sys.path
Relative imports - import something relative to the current module, must be a part of a package
If you're running both variants in exactly the same way, one of them should work. Here is an example that should help you understand what's going on. Let's add another main.py file with the overall directory structure like this:
.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py
And let's update test.py to see what's going on:
# config.py
debug = True
# test.py
print(__name__)
try:
# Trying to find module in the parent package
from . import config
print(config.debug)
del config
except ImportError:
print('Relative import failed')
try:
# Trying to find module on sys.path
import config
print(config.debug)
except ModuleNotFoundError:
print('Absolute import failed')
# main.py
import ryan.test
Let's run test.py first:
$ python ryan/test.py
__main__
Relative import failed
True
Here "test" is the __main__ module and doesn't know anything about belonging to a package. However import config should work, since the ryan folder will be added to sys.path.
Let's run main.py instead:
$ python main.py
ryan.test
True
Absolute import failed
And here test is inside of the "ryan" package and can perform relative imports. import config fails since implicit relative imports are not allowed in Python 3.
Hope this helped.
P.S.: If you're sticking with Python 3 there is no more need for __init__.py files.
You have to append your project's path to PYTHONPATH and make sure to use absolute imports.
For UNIX (Linux, OSX, ...)
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
For Windows
set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\
Absolute imports
Assuming that we have the following project structure,
βββ myproject
βββ mypackage
β βββ __init__.py
β βββ a.py
βββ anotherpackage
βββ __init__.py
βββ b.py
βββ c.py
βββ mysubpackage
βββ __init__.py
βββ d.py
just make sure to reference each import starting from the project's root directory. For instance,
# in module a.py
import anotherpackage.mysubpackage.d
# in module b
import anotherpackage.c
import mypackage.a
For a more comprehensive explanation, refer to the article How to fix ModuleNotFoundError and ImportError
python - ModuleNotFoundError: No module named - Stack Overflow
Python error "ImportError: No module named" - Stack Overflow
How to solve ModuleNotFoundError: No module named in Python?
Why do I get a ModuleNotFoundError?
Based on your comments to orip's answer, I guess this is what happened:
- You edited __init__.py on Windows.
- The Windows editor added something nonprinting, perhaps a carriage-return (end-of-line in Windows is CR/LF; in Unix it is LF only), or perhaps a Ctrl + Z (windows end-of-file).
- You used WinSCP to copy the file to your Unix box.
- WinSCP thought: "This has something that's not basic text; I'll put a .bin extension to indicate binary data."
- The missing __init__.py file (now called __init__.py.bin) means Python doesn't understand toolkit as a package.
- You create the __init__.py file in the appropriate directory and everything works...?
I ran into something very similar when I did this exercise in LPTHW; I could never get Python to recognise that I had files in the directory I was calling from. But I was able to get it to work in the end. What I did, and what I recommend, is to try this:
(NOTE: From your initial post, I am assuming you are using an *NIX-based machine and are running things from the command line, so this advice is tailored to that. Since I run Ubuntu, this is what I did)
Change directory (cd) to the directory above the directory where your files are. In this case, you're trying to run the
mountain.pyfile, and trying to call thetoolkit.interface.pymodule, which are in separate directories. In this case, you would go to the directory that contains paths to both those files (or in other words, the closest directory that the paths of both those files share). Which in this case is thetoolkitdirectory.When you are in the
toolkitdirectory, enter this line of code on your command line:export PYTHONPATH=.This sets your PYTHONPATH to ".", which basically means that your PYTHONPATH will now look for any called files within the directory you are currently in, (and more to the point, in the sub-directory branches of the directory you are in. So it doesn't just look in your current directory, but in all the directories that are in your current directory).
After you've set your PYTHONPATH in the step above, run your module from your current directory (the
toolkitdirectory). Python should now find and load the modules you specified.
I've got two scripts in my directory. Normally I would be able to import modules from one to another, but I'm suddenly getting this error:
ModuleNotFoundError: No module named modulename in Python
I've searched and tried solutions, but I don't think I properly understand how to solve it.
I'm not sure what's happened. When I check my working directory, os.getcwd() it spits out the correct one. All modules are in the same folder, and I used to be able to import them, until I added a new .py file. My original modules still work, even though they get the same error when i do:
import modulename
I can't tell if there's some structure I've missed, nor do I know how to check it, something like this
βββ test
βββ demoA
βββ __init__.py
β βββ test1.py
βββ demoB
βββ __init__.py
βββ test2.pyI should mention that the original directory (call it A) is forked, I haven't made or changed anything in it. So I must have messed something up. Should I delete my file and put it in a different directory (call it B)? If so, how do I call a specific .py file from A in my new B? It's my understanding that it needs to be in the same one, but I'm completely new to this, and basically know nothing. I just know that import module name should normally work :(
Hey Guys,
I get a weird ModuleNotFoundError in one of my projects and i do not really understand why. So here is my Folder Structure:
Project\
| main.py
| packageabc\
| | __init__.py
| | abc.py
| | packagexyz\
| | | xyz.py
In every .py file is an abc/xyz or main class. Now the interesting part. Inside the abc.py I do an import like this:
from packagexyz.xyz import xyz
This works perfectly fine!
Inside the main.py I do an import like this:
from packageabc.abcimport abc
Now I get an ModuleNotFoundError. Error Code looks like this:
from packagexyz.xyz import xyz ModuleNotFoundError: no module named packagexyz.
So the import in the abc.py File that works perfectly when tested inside the file does not work if the abc.py file is imported. So why is that?